关于spring:springboot自动配置的秘密

​前言

       随着互联网越来越风行,springboot曾经成为咱们无论是工作,还是面试当中,不得不把握的技术。说起springboot笔者认为最重要的性能非主动配置莫属了,为什么这么说?如果参加过以前spring简单我的项目的敌人必定,有过这样的经验,每次须要一个新性能,比方事务、AOP等,须要大量的配置,须要导出找jar包,时不时会呈现jar兼容性问题,能够说苦不堪言。

      springboot的呈现得益于“习惯优于配置”的理念,没有繁琐的配置、难以集成的内容(大多数风行第三方技术都被集成),这是基于Spring 4.x以上的版本提供的按条件配置Bean的能力。有了springboot的主动配置的性能,咱们能够疾速的开始一个我的项目。

一 什么是主动配置

不晓得敌人们在工作当中有没有这样的经验:

1.1 引入redisTemplate

只有咱们在pom.xml文件中引入spring-boot-starter-data-redis-xxx.jar包,而后只有在配置文件中配置redis连贯,如:

spring.redis.database = 0
spring.redis.timeout = 10000
spring.redis.host = 10.72.16.9
spring.redis.port = 6379
spring.redis.pattern = 1

就能够在service办法中间接注入StringRedisTemplate对象的实例,能够间接应用了。敌人们有没有想过这是为什么?

@Autowired
private StringRedisTemplate stringRedisTemplate;

1.2  引入transactionTemplate

在我的项目中只有引入spring-boot-starter-xxx.jar,事务就主动失效了,并且能够间接在service办法中间接注入TransactionTemplate,用它开发编程式事务代码。是不是很神奇?这又是为什么?

1.3  应用@ConfigurationProperties

应用@ConfigurationProperties能够把指定门路下的属性,间接注入到实体对象中,看看上面这个例子:

@Data
@Component
@ConfigurationProperties("jump.threadpool")
public class ThreadPoolProperties {
​
 private int corePoolSize;
 private int maxPoolSize;
 private int keepAliveSeconds;
 private int queueCapacity;
}

只有application.properties这样配置,就能够主动注入到下面的实体中

jump.threadpool.corePoolSize=8
jump.threadpool.maxPoolSize=16
jump.threadpool.keepAliveSeconds=10
jump.threadpool.queueCapacity=100

没错,这三个例子都是springboot主动配置在起作用,咱们分为两种状况:bean的主动配置 和 属性的主动配置。

二 工作原理


2.1 bean的主动配置

Spring Boot的启动类上有一个@SpringBootApplication注解,这个注解是Spring Boot我的项目必不可少的注解。

咱们先看看@SpringBootApplication注解

它下面定义了另外一个注解:@EnableAutoConfiguration

该注解的要害性能由@Import提供,其导入的AutoConfigurationImportSelector的selectImports()办法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具备META-INF/spring.factories的jar包上面key是EnableAutoConfiguration全名的,所有主动配置类。

咱们看看springboot的spring-boot-autoconfigure-xxx.jar

该jar包外面就有META-INF/spring.factories文件。

这个spring.factories文件是一组一组的key=value的模式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表,这些类名以逗号分隔。

@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(…)的外部就会执行selectImports()办法,找到所有JavaConfig主动配置类的全限定名对应的class,而后将所有主动配置类加载到Spring容器中。

SpringApplication.run(…)办法怎么调到selectImports()办法的

加载过程大略是这样的:

SpringApplication.run(…)办法  》 

AbstractApplicationContext.refresh()办法  》 

invokeBeanFactoryPostProcessors(…)办法  》 

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(…) 办法  》

ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(..)办法  》

AutoConfigurationImportSelector.selectImports

该办法会找到主动配置的类,并给打了@Bean注解的办法创建对象。

postProcessBeanDefinitionRegistry办法是最外围的办法,它负责解析@Configuration、@Import、@ImportSource、@Component、@ComponentScan、@Bean等,实现bean的主动配置性能。

回到刚刚第二个例子TransactionTemplate为什么能够间接援用?

是因为在spring-boot-autoconfigure-xxx.jar的spring.factories配置文件中,EnableAutoConfiguration全类名下配置了TransactionAutoConfiguration全类名,springboot在启动的时候会加载这个类。

而TransactionAutoConfiguration类是一个配置类,它外面创立TransactionTemplate类的实例。

这样在其余中央就能够间接注入TransactionTemplate类的实例。

2.2 属性的主动配置

属性的主动配置是通过ConfigurationPropertiesBindingPostProcessor类的postProcessBeforeInitialization办法实现,

public Object postProcessBeforeInitialization(Object bean, String beanName)
 throws BeansException {
 ConfigurationProperties annotation = getAnnotation(bean, beanName,
 ConfigurationProperties.class);
 if (annotation != null) {
 bind(bean, beanName, annotation);
 }
 return bean;
}

它会解析@ConfigurationProperties注解上的属性,将配置文件中对应key的值绑定到属性上。

三 主动配置的失效条件

每个xxxxAutoConfiguration类上都能够定义一些失效条件,这些条件根本都是从@Conditional派生进去的。

罕用的条件如下:

@ConditionalOnBean:当容器里有指定的bean时失效
@ConditionalOnMissingBean:当容器里不存在指定bean时失效
@ConditionalOnClass:当类门路下有指定类时失效
@ConditionalOnMissingClass:当类门路下不存在指定类时失效
@ConditionalOnProperty:指定的属性是否有指定的值,比方@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的状况下也为true。

举个比拟罕用的例子看看TransactionAutoConfiguration,是如何应用条件的

咱们能够看到,条件用的是:@ConditionalOnClass,示意TransactionAutoConfiguration类只有在PlatformTransactionManager类存在时才会失效。

如何自定义主动配置类?

请浏览《老司机手把手教你编写本人的springboot starter》外面有具体步骤。

总结

本篇文章从什么是主动配置,工作原理 和 主动配置的失效条件 三个方面介绍了主动配置的相干知识点。主动配置又分为:bean的主动配置 和 属性的主动配置,二者的实现原理不一样。主动配置的失效条件用得十分多,倡议敌人们好好钻研一下。至于如何自定义主动配置类,本篇没有讲,是因为我在另外一篇文章《老司机手把手教你编写本人的springboot starter》中认真介绍过的,有须要的敌人能够自行查阅。

如果这篇文档对您有所帮忙的话,麻烦关注一下我的公众账号:苏三说技术,或者帮忙点赞或转发,保持原创不易,您的反对是我保持最大的能源。前面我会分享更多更实用的干货,谢谢大家的反对。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理