SpringBoot的Starter机制

以spring-boot-starter-data-redis为例:

查看spring-boot-autoconfigure包中的META-INF/spring.factories:

可以发现 其中的org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的value中已经包含了RedisAutoConfiguration。

RedisAutoConfiguration类也是在spring-boot-autoconfigure包中的,spring-boot-autoconfiguration包把常用的插件的starter依赖的配置类都放了进来。

RedisAutoConfiguration类中:

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(
			RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(
			RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

}

@Bean:创建了两个Bean,第一个是根据注入的RedisConnectionFactory对象生成RedisTemplate对象,就是我们平时使用的RedisTemplate对象;第二个是根据注入的RedisConnectionFactory对象生成StringRedisTemplate对象。

@Configuration:表示它是一个配置类;

@EnableConfigurationProperties(RedisProperties.class):引入RedisProperties类中的配置,而RedisProperties.class类标识了@ConfigurationProperties(prefix="spring.redis"),说明了它会读取application.properties文件中以spring.redis为前缀的所有配置,并引入自己的成员变量中,成员变量有默认值,也就是对应的配置有默认值;

@Import({LettuceConnectionConfiguration.class,JedisConnectionConfiguration.class}):引入两个配置类,我们以JedisConnectionConfiguration.class为例进行说明:

JedisConnectionConfiguration类中:

@Configuration
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class })
class JedisConnectionConfiguration extends RedisConnectionConfiguration {

	private final RedisProperties properties;

	private final ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCustomizers;

	JedisConnectionConfiguration(RedisProperties properties,
			ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
			ObjectProvider<RedisClusterConfiguration> clusterConfiguration,
			ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCustomizers) {
		super(properties, sentinelConfiguration, clusterConfiguration);
		this.properties = properties;
		this.builderCustomizers = builderCustomizers;
	}

	@Bean
	@ConditionalOnMissingBean(RedisConnectionFactory.class)
	public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
		return createJedisConnectionFactory();
	}

...省略部分代码

看到了吧,我们上面创建RedisTemplate对象所需要依赖的RedisConnectionFactory对象在这里面创建的,这里面创建的Bean: JedisConnectionFactory是RedisConnectionFactory的子类。

在构造函数中,把前面引入的RedisProperties作为了参数。整个类配置类的作用就是根据RedisProperties中的配置来创建了一个JedisConnectionFactory对象。

但是这个配置类发挥作用是由前提的:必须包含@ConditionalOnClass中声明的类。其中JedisConnection.class在spring-data-redis包中,而Jedis.class在jedis包中,但JedisConnectionConfiguration配置类还是在spring-boot-autoconfiguration包中。如果你的pom依赖中没有spring-data-redis或jedis,那么@ConditionalOnClass中声明的类是会报红的,但是不会影响编译!SpringBoot可以根据@ConditionalOnClass选择性的进行加载,从而避免编译时报错,具体见代码:ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(),ConditionEvaluator.shouldskip()

总结:

在spring.factories中找到EnableAutoConfiguration对应的配置类;在具体的配置类中,引入@ConfigurationProperties类,这个类里面的成员变量对应了properties中的配置项;如果有依赖的Bean在其他包中,声明在@ConditionalOnClass中。然后再这个配置类中装配出最终变成需要的Bean即可。

很简单,不是么。现在你知道为什么简单地引入pom依赖包,简单地配置以下properties,就可以正常使用RedisTemplate类的原因了吧。

自己创建一个starter:

一般spring-boot-starter-xxx.jar包是官方已有的,不需要自己做,自己做的starter需要命名为xxx-spring-boot-starter。

1.创建META-INF/spring.factories文件,编辑好:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxx.xxx.xxx.MyAutoConfiguration

1、创建动态属性配置类MyProperties,标注@ConfigurationProperties, 与application.properties中的属性相对应;

2、写好MyAutoConfiguration配置类,通过@EnableConfigurationProperties引入MyProperties;

3、在当前项目的resources目录下新建 META-INF/spring.factories 文件里面内容如下:        org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxx.xxx.xxx.MyAutoConfiguration

将写好的spring-boot-starter-xxx.jar包引入,就可以直接使用里面自动装配好的Bean了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值