文章目录
springboot自动装配原理
1. @SpringBootApplication
我们先来看一下启动程序。
在启动类上面有一个@SpringBootApplication注解,这个注解表明这是一个SpringBoot应用,是SpringBoot项目的启动核心。
”Command+单击“冲进@SpringBootApplication注解里面,可以发现里面有一个组合注解:
2. @SpringBootConfiguration
先来分析@SpringBootConfiguration,点进去可以看见包含以下注解
此处主要看第四个注解@Configuration,表明这是一个配置类
3. @EnableAutoConfiguration
再来看看@EnableAutoConfiguration
从语意上来看,这是一个自动配置类。我们冲进去看一下源码
我们主要看后面两个注解:
- @AutoConfigurationPackage(自动配置包)
- @Import(AutoConfigurationImportSelector.class)(自动配置导入选择)
4. @Import(AutoConfigurationImportSelector.class)
@Import(AutoConfigurationImportSelector.class)的作用是导入AutoConfigurationImportSelector类,来到这里不禁引发疑问,导入这个类有什么用呢?
“Command+单击”进入AutoConfigurationImportSelector,我们来探究一下这个类在SpringBoot启动的过程中到底起了什么作用。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
- SpringApplication在运行Spring应用时,是通过SpringFactoriesLoader先调用loadFactoryNames再调用loadSpringFactories()方法,加载一些资源文件。
5. spring.factorie
我们找到META-INF/spring.factories工厂配置文件:
进入spring-factories文件,可以看到里面包含了很多自动配置属性:
以我们熟悉的redis为例,点进去
这里面放置了关于redis的配置,如将redisTemplate以@Bean标签标记
来到这里大致能先总结一下:
当我们的SpringBoot项目启动的时候,会先导入AutoConfigurationImportSelector,这个类会帮我们选择所有候选的配置,我们需要导入的配置都是SpringBoot帮我们写好的一个一个的配置类,那么这些配置类的位置,存在与META-INF/spring.factories文件中,通过这个文件,Spring可以找到这些配置类的位置,于是去加载其中的配置。
6. @ConditonalOnClass
但是有一个很实质的问题,springboot在启动的时候会将spring.factories文件中的配置全部加载吗?
很显然不会,但是springboot是如何辨认出哪些是我们项目需要的配置,哪些不是我们项目需要的配置呢?
这里就引进了一个注解@ConditonalOnClass。
简单解释这个注解的作用,即当某个class位于类路径上,才会实例化一个Bean。
在加载自动配置类的时候,并不是将spring.factories的配置全量加载进来,而是通过这个注解的判断,如果注解中的类都存在,才会进行加载。
下图以kafka自动配置文件为例,
当我们在pom.xml文件中加入Kafka的stater启动器时候,springboot启动项目的时候才会自动进行配置。
最终总结
- springboot核心思想:约定大于配置
注:
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
Springboot在启动过程中,会先导入AutoConfigurationImportSelector,这个类会加载项目中所有的META-INF/Spring.factories文件,文件中包含很多配置类,配置类上都有一个@Configuration注解,标识它是一个配置类,但是配置类不一定都生效,因为上面又有一个条件注解@ConditionOnClass,必须满足条件注解,配置类才会生效。我们只需要加入一个相关的启动器依赖,就可以使得条件注解生效,配置类也就生效了。
Memorial Day is 520 days |