1、springboot原理分析-自动配置-condition条件判断配置
2、springboot原理分析-自动配置-@Enable注解
3、springboot原理分析-自动配置-@import注解
前面三篇文字我们学习了springboot的自动配置的原理,我们今天就实用前面学习知识进行自定义starter,进而加深对前面三篇文章的学习效果。
文章目录
- 一、需求
- 二、实现步骤
- 1 创建 redis-spring-boot-autoconfigure 模块
- 1-1 创建项目
- 1-2 实现autoconfigure 模块
- 2 创建 redis-spring-boot-starter 模块,依赖 redis-spring-boot-autoconfigure的模块
- 3 在测试模块中引入自定义的 redis-starter 依赖,测试获取Jedis 的Bean,操作 redis。
- 3-1 创建测试模块:test-starter
- 3-2 修改启动类:
- 三、总结
- 四、优化
一、需求
今天我们要通过自定义redis-starter来加深前面三篇文章的理解。
要求当导入redis坐标时,SpringBoot自动创建Jedis的Bean。
创建项目redis-spring-boot-autoconfigure,用来配置redis-starter的核心配置。
pom文件为:
4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.8.RELEASE com.example redis-spring-boot-autoconfigure 0.0.1-SNAPSHOT redis-spring-boot-autoconfigure Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter redis.clients jedis
注意:删除pom 文件中的 / 标签。删除项目中的启动类,防止报错。
1-2 实现autoconfigure 模块1、我们在redis-spring-boot-autoconfigure 模块中写一个核心配置类RedisAutoConfiguration。
2、添加注解@Configuration
3、让配置类中提供jedis的bean就可以了。
package com.example.redis.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
@Configuration
public class RedisAutoConfiguration {
@Bean
public Jedis jedis() {
return new Jedis();
}
}
4、因为jedis 有很多构造函数,我们一般选择有参的构造函数:
public Jedis(String host, int port) {
super(host, port);
}
为此我们的RedisAutoConfiguration如下形式:
@Configuration
public class RedisAutoConfiguration {
@Bean
public Jedis jedis(RedisProperties redisProperties) {
return new Jedis("localhost", "6379");
}
}
但是上面的形式不方便我们的redis主机ip和端口的修改,为此我们需要让我们的实体类和配置文档绑定,从而让用户可以自定义配置这些主机ip和端口的参数。
5、添加RedisProperties类,绑定配置文件。
package com.example.redis.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "redis")
public class RedisProperties {
private String host = "localhost";
private int port = 6379;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
6、为例让ConfigurationProperties 实体类被启用,需要在RedisAutoConfiguration中进行配置EnableConfigurationProperties,让其生效,这样项目启动的时候,ConfigurationProperties就会注入到ioc容器中了。
7、下一步我们就可以通过参数的形式,将ConfigurationProperties,注入到jedis方法中,并使用。
package com.example.redis.config;
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {
@Bean
public Jedis jedis(RedisProperties redisProperties) {
System.out.println("注入的RedisProperties...."+redisProperties.toString());
return new Jedis(redisProperties.getHost(), redisProperties.getPort());
}
}
8、 在 redis-spring-boot-autoconfigure 模块中定义meta-INF/spring.factories 文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.example.redis.config.RedisAutoConfiguration
到此我们的edis-spring-boot-autoconfigure 配置完成。我们接下来看看如何使用。
2 创建 redis-spring-boot-starter 模块,依赖 redis-spring-boot-autoconfigure的模块其pom为:
3 在测试模块中引入自定义的 redis-starter 依赖,测试获取Jedis 的Bean,操作 redis。 3-1 创建测试模块:test-starter4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.8.RELEASE com.itheima redis-spring-boot-starter 0.0.1-SNAPSHOT redis-spring-boot-starter Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter com.example redis-spring-boot-autoconfigure 0.0.1-SNAPSHOT
pom:
3-2 修改启动类:4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.8.RELEASE com.example test-starter 0.0.1-SNAPSHOT test-starter Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter com.example redis-spring-boot-starter 0.0.1-SNAPSHOT
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class App {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(App.class, args);
Object jedis = run.getBean("jedis");
System.out.println(jedis);
}
}
启动打印日志:
到此,我们的自定义starter算是完成了。总结总结一下:
三、总结① 创建 redis-spring-boot-autoconfigure 模块,在此模块中初始化 Jedis 的Bean。并定义meta-INF/spring.factories 文件
② 创建 redis-spring-boot-starter 模块,依赖 redis-springboot-autoconfigure的模块
③ 在测试模块test-starter中引入自定义的 redis-starter 依赖,测试获取
Jedis 的Bean,操作redis。
我们可以在redis-spring-boot-autoconfigure 模块中做两处优化。
1、校验项目中是否引入了jedis
2、保证项目中仅仅初始化一个jedis 的bean
这两个地方主要通过RedisAutoConfiguration文件:
1、@ConditionalOnClass(Jedis.class)
2、@ConditionalOnMissingBean(name = "jedis")
package com.example.redis.config;
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
@ConditionalOnClass(Jedis.class)
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "jedis")
public Jedis jedis(RedisProperties redisProperties) {
System.out.println("RedisAutoConfiguration....");
return new Jedis(redisProperties.getHost(), redisProperties.getPort());
}
}



