上一篇,内容很少,说了一下SpringBoot的底层是怎么依赖的。这一篇讲一下SpringBoot底层源码是怎么实现的。
从SpringBoot的入口开始。第一篇的时候说过了,最好把入口文件放在最外层的包下面,至于原因就不多阐述了。
说说这个 @SpringBootApplication注解的原理,点进去看一下:
如下图:
主要就是这三个注解:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
@SpringBootConfiguration
SpringBootConfiguration这个注解是由Configuration注解实现的。
@Configuration
从名字上就可以判断出,这个注解是跟SpringBoot配置相关的,@Configuration,这个注解是Spring底层的一个注解,之前都是配置xml,SpringBoot推荐我们用配置类来描述配置,配置类是什么呢?就用@Configuration标记的类。
Configuration这个注解是由Component注解实现。
@Component
这个注解的意义就是,把当前的配置类添加到spring容器中,表示是一个组件。
@EnableAutoConfiguration
EnableAutoConfiguration这个注解是由AutoConfigurationPackage和@Import({AutoConfigurationImportSelector.class})注解实现
@AutoConfigurationPackage
这个注解从名字上面看出来是自动配置包,这是什么意思呢?在第一篇我们就说过了入口要放在最外层的包,至于原因,已经讲过了,因为SpringBoot会自动将引导类 @SpringBootApplication标注的类所在的包以及下面所有子包里面所有的组件扫描到Spring容器中统一管理。就是这个注解实现的。那么,这个注解是怎么实现的呢?就是通过它的这个 @Import({Registrar.class}),下面就是Registrar类的源码了
1 | static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { |
就是通过下面这个代码注册进去的。
1 | AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName()); |
@Import({AutoConfigurationImportSelector.class})
这个注解是干什么用的呢?
- 它会把项目里面所有需要导入的组件以全类名的方式返回,将这些组件添加到容器中。
- 会给容器中注入非常多的自动配置类,就是导入并配置好当前项目中
所需要的组件,省去我们手动编写配置去注入组件。
怎么实现的呢?打开AutoConfigurationImportSelector类,找到如下代码:
1 | List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); |
找到getCandidateConfigurations方法,如下:
1 | protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { |
找到loadFactoryNames方法,如下:
1 | public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) { |
找到loadSpringFactories方法,里面有
1 | Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories"); |
这里就是我们的配置,我们这个配置具体是在哪呢?如下图
@ComponentScan
这个注解的主要作用就是,被该注解标识的类会被Spring容器纳入管理。