浅析springboot自动装配原理

先看一下springboot项目的主配置类:
springboot的主配置类可以看到springboot主配置类只有一个注解:@SpringBootApplication
我们可以先提出一个疑问:是不是就是这个注解在底层就完成了自动装配的工作?
接下来就是对这个注解进行研究,我们先点进去这个注解,可以看到下图:
@SpringBootApplication注解的底层
这个注解下面混合了以下这些注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
前四个注解都是在定义注解中最基础的部分,因此不做讨论,我们之研究下面三个注解。
首先是@SpringBootConfiguration注解,我们点进这个注解可以看到下图@SpringBootConfiguration注解的底层
可以看到刨除前三个基础注解外,仅仅只有一个@Configuration注解,我们都知道这个注解一般都是用于标识配置类的,因此这个类仅仅是一个简单的配置类而已,因此不做研究。
其次是@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })注解,我们点进这个注解可以看到下图:@ComponentScan注解的底层
可以看到这个注解仅仅是用于包扫描的,因此也可以确定它不参与自动装配。
最后我们来点进@EnableAutoConfiguration看一下这个注解是用来做什么的,如下图:@EnableAutoConfiguration注解的底层
这个类里面一共有两个非基础注解,我们先看第一个@AutoConfigurationPackage注解
@AutoConfigurationPackage注解的底层
我们点进去可以看到只有一个@Import注解,我们知道这个注解一般用于导包,我们点进这个类里看看到底这里导的是哪个包:@Import注解
我们可以看到在这个类里有一句new PackageImports(metadata).getPackageNames().toArray(new String[0]),我们在这里打一个断点来看一下这一句究竟是在导什么包:
在这里插入图片描述
我们通过Evaluate Expression来看看是否能获取扫描的包路径:在这里插入图片描述

可以看到这里的路径和我的项目路径一样,因此可以推断这里是将我的项目包直接注册进了容器中,也因此可以推断Registrar类的作用是在将某一个包下的组件批量注册进容器中。
这个注解可以看到到这里已经结束了,我们来点进另一个注解导入的包看看它有什么作用:在这里插入图片描述
点进来可以看到这是一个导入选择器,在这个类下面有一个selectImports方法:在这里插入图片描述
这个方法里有一句AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);我们直接点进getAutoConfigurationEntry这个方法里,看看这个方法最后返回的是一个什么值:在这里插入图片描述
可以看到在这个方法里configurations从开始到最后一直在运行,我们对List configurations = getCandidateConfigurations(annotationMetadata, attributes);这一句debug一下,看看到底是什么东西:在这里插入图片描述
可以看到这个configurations一共有130个数据,这些数据又是从哪里来的,我们点进getCandidateConfigurations方法中看看:在这里插入图片描述
可以看到这个方法里有一个工厂加载器在这里插入图片描述
我们点进工厂加载器看看里面是什么:在这里插入图片描述
可以看到这一句:public static final String FACTORIES_RESOURCE_LOCATION = “META-INF/spring.factories”;
这一句保存了这个文件的META-INF地址,我们打开spring-boot-autoconfigure-2.4.1.jar自动配置jar包里可以见到这个文件:在这里插入图片描述
在这个文件里有一个标注了自动配置的目录,在这下面全是一些自动配置类的全限定类名在这里插入图片描述
可以看到一直从第22行一直持续到151行,计算一下:151-22+1=130,可以看到刚好是130个,因此可以推断上文configurations的数据来自这个文件,我们可以推测springboot项目在启动时从类路径下的META-INF/spring.factories中获取这些已经写死的值,然后再将这些值对应的自动配置类导入容器中,从而做到自动配置。
那么这些自动配置是在项目开始运行时会全部生效的吗?我们可以随便找一个自动配置类看一下:在这里插入图片描述
我找的例子是aop的自动配置类,可以看到这里有一个标红的@ConditionalOnClass(Advice.class)注解,这个注解的作用是用于条件装配,在有Advice这个类时才会运行在这里插入图片描述
可以看到这个类并没有被导入,因此没有运行,由此可以推出:springboot项目在启动时虽然将所有自动配置类导入容器中默认加载,但是却没有全部都生效,而是按需进行配置,在给某个自动配置类加上特定的场景后才会生效。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值