SpringBootApplication解密
SpringBoot 2.0.6 版本为例
@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}
)}
)
public @interface SpringBootApplication {}
- @Target({ElementType.TYPE}):指明了修饰的这个注解的使用范围为类,接口或者枚举
- @Retention(RetentionPolicy.RUNTIME):指明修饰的注解的生存周期为运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。
- @Documented:指明修饰的注解,可以被例如javadoc此类的工具文档化
- @Inherited:允许子类继承父类中的注解
- @interface意思是声明一个注解,方法名对应参数名,返回值类型对应参数类型。
接下来的三个注解才是重中之重
- @SpringBootConfiguration
点进去查看代码,发现@Configuration注解,原来是spring全家桶时代的注解,作用是申明一个配置类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@Configuration点进去发现是@Component注解的实现,而@Component意思是把当前的配置类添加到spring容器中,表示是一个组件
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
所以这个注解没什么新东西
- @ComponentScan
这个注解的主要作用就是,被该注解标识的类会被Spring的IOC容器纳入管理,比如@Controller,@Service,@Repository注解,查看其源码你会发现,他们中有一个共同的注解@Component,所以被它们注解的类会被Spring的IOC容器纳入管理
- excludeFilters:按照规则排除某些包的扫描
- includeFilters:按照规则只包含某些包的扫描
也没啥新东西,权当复习
3.@EnableAutoConfiguration
@EnableAutoConfiguration的作用是启动自动配置,意思是Spring Boot会根据你添加的jar包来配置你项目的默认设置,比如你添加了Spring Boot提供的spring-boot-starter-web依赖,其中包含了Tomcat和Spring MVC,这个注释就会认为你正在开发一个Web应用程序,自动地帮你添加Web项目中所需要的Spring配置。
点进去查看代码,分析具体实现
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@AutoConfigurationPackage:自动配置包
@Import({AutoConfigurationImportSelector.class}):它会把项目里面所有需要导入的组件以全类名的方式返回,将这些组件添加到容器中。而且会给容器中注入非常多的自动配置类,导入并配置好当前项目中所需要的组件。
这是如何实现的呢?进入AutoConfigurationImportSelector.class找到selectImports()方法里面的getCandidateConfigurations()方法
然后进入getCandidateConfigurations方法找到loadFactoryNames方法,再进入loadFactoryNames方法找到loadSpringFactories(),里面有这段代码classLoader.getResources("META-INF/spring.factories"),表示去META-INF/spring.factories中寻找需要加载的自动配置类(xxxAutoConfiguration)
可以看到spring.factories中有很多以xxxAutoConfiguration命名的配置类
包括CacheAutoConfiguration和RabbitAutoConfiguration