SpringBoot 2.X自动装配原理

  • 什么是自动配置?自动配置原理?

    1. SpringBoot所谓的自动配置是基于JavaConfig技术(配置类 + 注解的方式)的,而不是XML
    2. SpringBoot会根据当前(环境)依赖自动应用一些JavaConfig来做配置
    3. SpringBoot会通过一些条件筛选判断是否需要某个配置(动态插拔)
  • 原理

    @SpringBootApplication
    public class DemoApplication {
       public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args); }
    }
    

    @SpringBoot是一个复合注解,其中有

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    // 以上为原注解
    @SpringBootConfiguration // 表明当前类是一个根配置类(级别较@Configuration高)
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}
    )
    public @interface SpringBootApplication { ... ...}
    

    在@EnableAutoConfiguration中

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    // 以上为原注解
    @AutoConfigurationPackage // 作用是自动加载扫描包的路径(这也是为什么SpringBoot应用的启动类总是在最外层的原因)
    @Import({AutoConfigurationImportSelector.class})
    public @interface EnableAutoConfiguration {... ...}
    

    而@Import注解会将AutoConfigurationImportSelector.class注入到IOC容器中

    public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
        ... ...
        // 此方法实现至DeferredImportSelector接口
        // 而DeferredImportSelector又继承自ImportSelector接口
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
           if (!this.isEnabled(annotationMetadata)) {
               return NO_IMPORTS;
           } else {
               AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
               return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
          }
       }
        ... ...    
    }
    

    ImportSelector接口:SpringBoot自动配置的核心

    public interface ImportSelector {
        // 返回一个String数组,数组里的内容是一些类的路径名称,Spring会把这个数组返回的路径名称的类加载注入到IOC容器中
        String[] selectImports(AnnotationMetadata var1);
    	... ...
    }
    

    String[ ] selectImports 是如何加载类路径信息的?

    AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
    

    this.getAutoConfigurationEntry(annotationMetadata)

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
           ... ...
           List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
           ... ...
        }
    }
    

    this.getCandidateConfigurations(annotationMetadata, attributes)

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    	... ...
    }
    

简而言之selectImports方法最终会找到spring.factories文件,并扫描这个文件,将里面的配置类加载到IOC容器中
在这里插入图片描述

实际上这些以xxxAutoConfiguration结尾的文件就是一个个的JavaConfig,它能将配置文件中配置的属性与标注着有@ConfigurationProperties的类文件中的相应的属性进行绑定。例如:server.port / spring.application.name / spring.rabbitmq.localhost等属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值