SpringBoot 自动装配原理

2022-11-05  本文已影响0人  小二上酒8

Sping Boot 如何实现自动配置

Spring Boot都需要创建一个mian启动类,而启动类都含有@SpringBootApplication注解,从启动类,一步步探索源码。

@SpringBootApplication注解

Spring Boot 启动类上都有一个 @SpringBootApplication注解:

@EnableAutoConfiguration注解

@SpringBootApplication 里面有 @EnableAutoConfiguration 的注解:

AutoConfigurationImportSelector类

@EnableAutoConfiguration注解导入AutoConfigurationImportSelector类:

selectImports()方法

AutoConfigurationImportSelector类找到 selectImports 方法,里面有getAutoConfigurationEntry方法:

SpringFactoriesLoader.loadFactoryNames() 方法

getAutoConfigurationEntry方法通过SpringFactoriesLoader.loadFactoryNames() 扫描所有含有META-INF/spring.factoriesjar包:

spring-boot-autoconfigure-xxx.jar项目包含META-INF/spring.factories文件,spring.factories是一个键值对的形式,扫描该文件下@EnableAutoConfiguration对应类:

自动配置主要由@EnableAutoConfiguration实现,添加了@EnableAutoConfiguration注解,会导入AutoConfigurationImportSelector类,里面的selectImports方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有含有META-INF/spring.factoriesjar包,将对应key@EnableAutoConfiguration注解全名对应的value类全部装配到IOC容器中。

Debug 验证

打开Debug调式模式,在getCandidateConfigurations方法里面的SpringFactoriesLoader.loadFactoryNames()处设置断点,查看返回的configurations集合:

第一个元素是tk.mybatis.mapper.autoconfigure.MapperAutoConfiguration是因为引入了通用mapper的依赖:

自动配置原理

原理流程汇总

从上面查看的源码,可以知道Spring Boot自动配置主要是@EnableAutoConfiguration实现的,@EnableAutoConfiguration注解导入AutoConfigurationImportSelector类,通过selectImports方法调用SpringFactoriesLoader.loadFactoryNames()扫描所有含有META-INF/spring.factories文件的jar包,将spring.factories文件中@EnableAutoConfiguration对应的类注入到IOC容器中。

这些属性自动配置到IOC之后就无需自己手动配置bean了,Spring Boot中的约定大于配置理念,约定是将需要的配置以约定的方式添加到IOC容器中。

自动配置生效条件

那是不是spring.factories文件对应的配置都会加载到IOC容器中?比如下面的Kafka自动配置类:

@Configuration
@ConditionalOnClass(KafkaTemplate.class)
@EnableConfigurationProperties(KafkaProperties.class)
@Import({ KafkaAnnotationDrivenConfiguration.class, KafkaStreamsAnnotationDrivenConfiguration.class })
public class KafkaAutoConfiguration {

    private final KafkaProperties properties;

    private final RecordMessageConverter messageConverter;

    public KafkaAutoConfiguration(KafkaProperties properties, ObjectProvider<RecordMessageConverter> messageConverter) {
        this.properties = properties;
        this.messageConverter = messageConverter.getIfUnique();
    }

    @Bean
    @ConditionalOnMissingBean(KafkaTemplate.class)
  public KafkaTemplate<?, ?> kafkaTemplate(ProducerFactory<Object, Object> kafkaProducerFactory,
            ProducerListener<Object, Object> kafkaProducerListener) {
      ....
      }

其中有几个注解:

@ConditionalOnClass
@ConditionalOnMissingBean
复制代码

所以spring.factories里面并不是所有的bean都会装配到IOC容器中,只会按需配置对应的bean

总结

上一篇下一篇

猜你喜欢

热点阅读