SpringBoot自动装配原理

SpringBoot自动装配原理

要先了解SpringBoot自动装配原理我们就得了解@SpringBootApplication注解,他是由三个注解组合成的也就是@ComponentScan(扫描包)和@SpringBootConfiguration(本质就是@Configuration,扫描配置的注解)以及最重要的@EnableAutoConfiguration(自动装配注解)

@ComponentScan

 

其实也就是Spring的扫描注解,使得@SpringBootApplication实现了自动扫描父包和子包,这样使得我们的APP启动类要放在项目包下面,当然我们放在其他地方也可以,但是需要自己配置扫描路径,

我们以前需要配置包扫描器<context:component-scan base-package="com.test"/>.

@ComponentScan("com.test") 扫描包。

@SpringBootConfiguration

 

其实SpringBootConfiguration也就是@Configuration注解,他就是javaConfig形式的Spring Ioc容器的配置类使用的@Configuration,本身其实也是一个Ioc容器,以前是使用xml配置的,现在简化开发使用的Bean的来源。

@EnableAutoConfiguration

 

@EnableAutoConfiguration是一个复合注解,它其中最关键的注解便是@Import(EnableAutoConfigurationImportSelector.class)和@AutoConfigurationPackage

@AutoConfigurationPackage 里面其实是@Import(Registrar.class)里面存放的其实是包扫描器传过来的,也就是自动注册表。

@Import(EnableAutoConfigurationImportSelector.class)就比较重要了,它一路走下去就是加载了所有在META-INF下面的spring.factories中的自动装配对象,前提是我们导入了对应的启动类。也就是帮助了SpringBoot引用所有符合条件的@Configuration配置到当前SpringBoot所创建的Ioc容器中,就像一个八爪鱼一样借助于Spring原框架的一个工具类:SpringFactoriesLoader。这才使得@EnableAutoConfiguration自动装配的功能实现。

 

这个注解也是一个派生注解,主要的功能由@Import提供。@Import(AutoConfigurationImportSelector.class)

这是AutoConfigurationImportSelector的主要方法

 

它又调用了

AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
      autoConfigurationMetadata, annotationMetadata);

 

List<String> configurations = getCandidateConfigurations(annotationMetadata,
      attributes);

 

configurations里面有120个东西就是我们的META-INF/spring.factories里面的jar包我们继续往下走看它是怎么得到的。

 

这时候我们看到

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
      getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());

 

是不是很熟悉的方法loadFactoryNames这个方法扫描了了所有具有META-INF/spring.factories的jar包,

classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :

 

@EnableAutoConfiguration通过@Import(AutoConfigurationImportSelector.class)调用AutoConfigurationImportSelector中的selectImports调用getAutoConfigurationEntry中的getCandidateConfigurations的SpringFactoriesLoader.loadFactoryNames方法中的

Enumeration<URL> urls = (classLoader != null ?
      classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
      ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
      
      public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

FACTORIES_RESOURCE_LOCATION中存的就是所有带的jar包。

而在spring.factories文件也是一组一组的k-v的形式,k就是EnableAutoConfiguration的全类名,v是xxxxAutoConfiguration的类名的列表,用逗号隔开

 

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

自动配置生效

每一个XxxxAutoConfiguration自动配置类都是在某些条件之下才会生效的,这些条件的限制在Spring Boot中以注解的形式体现,常见的条件注解有如下几项

@ConditionalOnBean:当容器里有指定的bean的条件下。 @ConditionalOnMissingBean:当容器里不存在指定bean的条件下。 @ConditionalOnClass:当类路径下有指定类的条件下。 @ConditionalOnMissingClass:当类路径下不存在指定类的条件下。

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

在这个类上有个ConfigurationProperties注解,他的作用就是从配置文件中绑定属性到对应的bean上,而@EnableConfigurationProperties负责导入已经绑定了属性的bean到Spring容器中,那么所有和他相关的属性都可以在全局配置文件中定义,限制全局配置文件中配置那些属性就是XxxxProperties类,他与配置文件中定义的prefix关键字开头的一组属性是唯一对应的。

全局配置文件中的属性通过@ConfigurationProperties注解绑定到对应的Properties配置实体类上封装为一个bean,再通过@EnableConfigurationProperties注解导入到Spring容器中。

而诸多的XxxxAutoConfiguration自动配置类,就是Spring容器的JavaConfig形式,作用就是为Spring 容器导入bean,而所有导入的bean所需要的属性都通过xxxxProperties的bean来获得。

面试解答

Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如:server.port,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。

当然不是所有的jar包我们都用的上,当我们导入了对应的启动器他才能供我们使用详情看这里

 

这些是条件注解,只有导入了启动类,条件注解检测到了有对应的类,这个类才会自动化配置。

最后奉上大图

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值