spring boot自动装配原理详解

如何将自动配置类加载到Spring容器中?

springboot的启动类有一个@SpringBootApplication注解 ,这个注解是spring boot自动装配原理的关键。

@SpringBootApplication注解是一个复合注解,里面包含一个@EnableAutoConfiguration注解。

@EnableAutoConfiguration的定义如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {

@EnableAutoConfiguration里面有一个@Import注解,它们之间的注解链如下:

// 注解链
@SpringBootApplication
	=> @EnableAutoConfiguration
		=> @Import(EnableAutoConfigurationImportSelector.class)

Springboot应用启动过程中使用ConfigurationClassParser分析配置类时 ,ConfigurationClassParser会实例化一个 EnableAutoConfigurationImportSelector 并调用它的 selectImports() 方法。

selectImports() 方法内部使用了spring内部工具SpringFactoriesLoader,扫描当前应用classpath下所有META/spring.factories元信息配置。这个spring.factories文件也是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的接口,而它的value是对应接口的实现类全路径的列表,这些类名以逗号分隔 。找到所有JavaConfig自动配置类的全限定名对应的class,根据这些类路径,然后将所有自动配置类加载到Spring容器中。

下图是自动装配的整个流程:
在这里插入图片描述

全局配置文件中的属性如何生效?

以ServletWebServerFactoryAutoConfiguration配置类为例,解释一下全局配置文件中的属性如何生效,比如:server.port=8081,是如何生效的(当然不配置也会有默认值,这个默认值来自于org.apache.catalina.startup.Tomcat)。

在这里插入图片描述

在ServletWebServerFactoryAutoConfiguration类上,有一个@EnableConfigurationProperties注解:开启配置属性,而它后面的参数是一个ServerProperties类,这就是习惯优于配置的最终落地点。

在这个类上,我们看到了一个非常熟悉的注解:@ConfigurationProperties,它的作用就是从配置文件中绑定属性到对应的bean上,而@EnableConfigurationProperties负责导入这个已经绑定了属性的bean到spring容器中(见上面截图)。那么所有其他的和这个类相关的属性都可以在全局配置文件中定义,也就是说,真正“限制”我们可以在全局配置文件中配置哪些属性的类就是这些XxxxProperties类,它与配置文件中定义的prefix关键字开头的一组属性是唯一对应的。

一定要记得XxxxProperties类的含义是:封装配置文件中相关属性;XxxxAutoConfiguration类的含义是:自动配置类,目的是给容器中添加组件。

而其他的主方法启动,则是为了加载这些五花八门的XxxxAutoConfiguration类。

自动配置生效条件

当然, EnableAutoConfiguration通过SpringFactoriesLoader筛选并加载进来的这些Java配置类里面,我们其实还可以进一步对要加载到容器的bean定义进行筛选, 这就会用Spring3系列引入的@Conditional“军团”, 通过像@ConditionalOnClass, @ConditionalOnMissingBean等具体的类型和条件来进一步决定加载还是不加载哪些bean定义。

常见的条件注解有如下几项:

@ConditionalOnBean:当容器里有指定的bean的条件下。

@ConditionalOnMissingBean:当容器里不存在指定bean的条件下。

@ConditionalOnClass:当类路径下有指定类的条件下。

@ConditionalOnMissingClass:当类路径下不存在指定类的条件下。

@ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。

参考文章:
https://blog.csdn.net/u014745069/article/details/83820511

https://afoo.me/posts/2015-07-09-how-spring-boot-works.html

https://blog.csdn.net/andy_zhang2007/article/details/78580980

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值