0
点赞
收藏
分享

微信扫一扫

19-SpringBoot自动配置-自定义starter实现

19-SpringBoot自动配置-自定义starter实现

前言

在前面我们使用了不少 SpringBoot 的起步依赖,例如 mybatis 、 redis 等起步依赖。那么本篇章,我们首先参考 mybatis 的起步依赖分析,然后自己写一个 redisTemplate 的起步依赖。

自定义starter步骤分析

1. 分析 mybatis 起步依赖的步骤

1.1 查询获取 mybatis 的起步依赖

访问 https://mvnrepository.com/ 搜索 mybatis-spring-boot


19-SpringBoot自动配置-自定义starter实现_maven19-SpringBoot自动配置-自定义starter实现_spring_02

<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>

1.2 在项目设置 mybatis 起步依赖

19-SpringBoot自动配置-自定义starter实现_mybatis_03

一般第三方的应用取名的规则 xxxxx-spring-boot-starter,例如 mybatis 的 mybatis-spring-boot-starter


1.3 进入 mybatis-spring-boot-starter 查看里面包含的坐标,如下:


19-SpringBoot自动配置-自定义starter实现_java_0419-SpringBoot自动配置-自定义starter实现_mybatis_05

也就是说起步依赖是必须有一个自动配置的功能的。

1.4 从 jar 包来查看源码


19-SpringBoot自动配置-自定义starter实现_maven_0619-SpringBoot自动配置-自定义starter实现_maven_0719-SpringBoot自动配置-自定义starter实现_java_08

基于mybatis起步依赖的结构,我们可以总结一下如何写一个redis的起步依赖。

2. 自定义 redis 起步依赖的步骤

需求:自定义redis-starter。要求当导入redis坐标时,SpringBoot自动创建Jedis的Bean。

步骤:

①创建 redis-spring-boot-autoconfigure 模块

②创建 redis-spring-boot-starter 模块,依赖 redis-spring-boot-autoconfigure的模块

③在 redis-spring-boot-autoconfigure 模块中初始化 Jedis 的 Bean。并定义META-INF/spring.factories 文件

④在测试模块中引入自定义的 redis-starter 依赖,测试获取 Jedis 的Bean,操作 redis。

自定义starter实现

1.创建redis-spring-boot-autoconfigure配置工程


19-SpringBoot自动配置-自定义starter实现_mybatis_09

2.创建redis-spring-boot-starter工程


19-SpringBoot自动配置-自定义starter实现_java_10

pom文件中引入redis-spring-boot-autoconfigure


19-SpringBoot自动配置-自定义starter实现_spring boot_11

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- SpringBoot 父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<!-- 工程坐标 -->
<groupId>com.lijw</groupId>
<artifactId>redis-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>

<!-- 工程信息 -->
<name>redis-spring-boot-starter</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>

<!-- 工程依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- 引入autoconfigure -->
<dependency>
<groupId>com.lijw</groupId>
<artifactId>redis-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

</dependencies>


</project>

3.【redis-spring-boot-autoconfigure】设置引入 jedis 依赖


19-SpringBoot自动配置-自定义starter实现_maven_12

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- SpringBoot 父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<!-- 工程坐标 -->
<groupId>com.lijw</groupId>
<artifactId>redis-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>

<!-- 工程信息 -->
<name>redis-spring-boot-autoconfigure</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>

<!-- 工程依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<!--引入jedis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>

</project>

4.【redis-spring-boot-autoconfigure】编写 RedisAutoConfiguration 自动配置类 以及 RedisProperties 获取配置信息类

在 redis-spring-boot-autoconfigure 模块中初始化 Jedis 的 Bean。并定义META-INF/spring.factories 文件

4.1 编写自动配置类


19-SpringBoot自动配置-自定义starter实现_java_13

package com.lijw.redis.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;

@Configuration
public class RedisAutoConfiguration {

/**
* 提供Jedis的bean
* @return
*/
@Bean
public Jedis jedis(){
return new Jedis(); // 没有设置host、port
}

}

在这里我们返回Jedis的时候没有配置 host 以及 port,我们在下面的配置信息类中设置。

4.2 编写 RedisProperties 获取配置信息类

首先参考 mybatis 的自动配置类中的 META-INF/spring.factories 文件进行编写,如下:


19-SpringBoot自动配置-自定义starter实现_maven_14

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.lijw.redis.config.RedisAutoConfiguration

编写 RedisProperties 读取配置:


19-SpringBoot自动配置-自定义starter实现_spring boot_15

package com.lijw.redis.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "redis")
public class RedisProperties {

private String host = "localhost"; // 默认本地
private Integer port = 6379; // 默认端口号

public String getHost() {
return host;
}

public void setHost(String host) {
this.host = host;
}

public Integer getPort() {
return port;
}

public void setPort(Integer port) {
this.port = port;
}
}

4.3 编写 自动配置类  引入 配信信息


19-SpringBoot自动配置-自定义starter实现_java_16

package com.lijw.redis.config;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;

@Configuration
@EnableConfigurationProperties(RedisProperties.class) // 启用配置信息类
public class RedisAutoConfiguration {

/**
* 提供Jedis的bean
*
* @return
*/
@Bean
public Jedis jedis(RedisProperties redisProperties) {
return new Jedis(redisProperties.getHost(), redisProperties.getPort()); // 动态获取配置文件的host、port
}

}

5.【springboot-enable】在之前的项目中引入自定义 redis 起步依赖,创建 bean

5.1 配置 pom 加入依赖


19-SpringBoot自动配置-自定义starter实现_spring_17

<!--   引入自定义的redis启动依赖     -->
<dependency>
<groupId>com.lijw</groupId>
<artifactId>redis-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

5.2 创建 jedis 的 bean


19-SpringBoot自动配置-自定义starter实现_mybatis_18

@SpringBootApplication
public class SpringbootEnableApplication {

public static void main(String[] args) {
// 获取IOC容器
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
// 其他工程
Object jedis = context.getBean("jedis");
System.out.println(jedis);

}

}

可以看到我们已经成功获取到 jedis 的 bean 了。

5.3 尝试执行redis的操作


19-SpringBoot自动配置-自定义starter实现_maven_19

// 获取IOC容器
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
// 其他工程
Jedis jedis = context.getBean(Jedis.class);
System.out.println(jedis);

// redis操作
jedis.set("key_order", "id123345");
String key_order = jedis.get("key_order");
System.out.println(key_order);

可以看到也成功执行 redis 操作了。

5.4 在配置文件故意填写错误的 redis 端口号,验证自定义redis启动依赖能否获取配置


19-SpringBoot自动配置-自定义starter实现_java_20

redis.port=66666

执行验证效果:


19-SpringBoot自动配置-自定义starter实现_mybatis_21

6.【redis-spring-boot-autoconfigure】设置加载Bean的条件


19-SpringBoot自动配置-自定义starter实现_spring boot_22

package com.lijw.redis.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;

@Configuration
@EnableConfigurationProperties(RedisProperties.class) // 启用配置信息类
@ConditionalOnClass(Jedis.class) // 当不存在Jedis类的Bean才去加载
public class RedisAutoConfiguration {

/**
* 提供Jedis的bean
*
* @return
*/
@Bean
@ConditionalOnMissingBean(name = "jedis") // 当用户没有自定义名称为jedis的Bean,才去加载该Bean
public Jedis jedis(RedisProperties redisProperties) {
System.out.println("RedisAutoConfiguration....."); // 用于校验是否执行了该Bean方法
return new Jedis(redisProperties.getHost(), redisProperties.getPort());
}

}

7.【springboot-enable】验证自动配置的条件

首先我们先执行执行一下看看:


19-SpringBoot自动配置-自定义starter实现_java_23

那么我们再下方自己定义一个 jedis 的 bean 方法,看看会不会将其覆盖:


19-SpringBoot自动配置-自定义starter实现_mybatis_24

可以看出加载的是下方定义的 bean 方法,没有从自定义 redis 起步依赖中加载。也就是条件 @ConditionalOnMissingBean(name = "jedis") 生效了。



举报

相关推荐

0 条评论