SpringBoot自动装配底层原理

@SpringBootApplication注解内部

681bed6ecefdc816cf5243f995c37f0f.png

可以看到该注解上的常规注解有这几个:

  • @Target :  用来指明@SpringBootApplication这个注解添加的位置
  • @Retention :用来指定@SpringBootApplication这个注解的生命周期
  • @Documented :添加后@SpringBootApplication这个注解可以出现在帮助文档
  • @Inherited:表示@SpingBootApplication这个注解可以被子类继承

三个重要注解

现在来看后面三个比较重要注解

@SpringBootConfiguration 

c240153b6d6c775b7ca197efaa101882.png

可以看到除了常规注解@Target@Retention@Documented外只多了两个注解

@Configuration:用来指明该类也是配置类

@Indexed:用来加速应用启动

@ComponentScan

用来指定默认组件的扫描范围,默认是当前包及其子包

注意:如果手动配置了扫描范围,则默认的扫描会失效

通过上面可以看出来以上注解都不是自动装配的核心,那么真相只有一个

@EnableAutoConfiguration

@EnableAutoConfiguration

来看@EnableAutoConfiguration内部

3327e900edb73c87e3b75cc040fa1d28.png

可以看到它除了常规注解外,多了两个@AutoConfigurationPackage和@Import注解

@AutoConfigurationPackage:指定SpringBoot默认扫描包

那么关键就在@Import这个注解,我们先看看下这个注解的作用

@Import

可以将其中的类添加给IOC容器管理,这里添加了AutoConfigurationImportSelector.class

来看这个类

AutoConfigurationImportSelector类

c617c20d113380bf0c8bfbfa9ecf1834.png

我们可以看到他实现的第一个接口就是DeferredImportSelector,来看DeferredImportSelector这个接口

c445973c25657c0ad4404b58a24b56f8.pngDeferredImportSelectorr又继承了ImportSelector类,来看ImportSelector这个类

8de3e7cebd48856629cc59111e5fd39c.png

可以看到类有两个方法

1、selectImports

2、getExclusionFilter 

而getExclusionFilter用default修饰有了默认实现,return  null ;

因此关键就在selectorImports这个方法,说明下:

该方法的返回值是字符串数组,该数组中所有类都会被IOC容器管理

885938ea37d878f88c1de448c486957e.png

那么AutoConfigurationImportSelector作为其继承类,就需要重写该方法。我们来看下在AutoConfigurationImportSelector中重写的SelectorImports方法

selectImports方法

cfb6cf878e40e7cd443aa0ee7792dba1.png

可以看到该方法返回的是autoConfigurationEntry.getConfigurations()

而autoConfigurationEntry是this.getAutoConfigurationEntry方法获取的

来看getAutoConfigurationEntry方法

f7c6cfb7543c9be560f224dd9ffe8a92.png可以看到该方法返回的AutoConfigurationEntry对象有两个重要属性

configurations和exclusions,通过名字可以判断出configurations集合就是关键

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

来看这个集合怎么获取的,通过getCandidateConfigurations方法

getCandidateConfigurations方法

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));
        ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

通过代码我们可以看到他是读取

META-INF/spring.factories nor in 
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

这个两个文件,将其中数据封装到configurations集合中。那么该文件中是什么内容呢

b23e4f20141f76fffc6677cfde5a8169.png

610d1d1bf041eb7a9bcdf5d52715179f.png

一百多个配置类的全类名

注意:并不是AutoConfiguration文件中所有类都装入IOC容器中。需要满足@ConditionalOnMissingBean条件判断来判断是否交给IOC管理

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值