@SpringBootApplication是SpringBoot项目的核心注解,目的是开启自动配置。
annotation
以下是@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) })
public @interface SpringBootApplication {
注:java中@interface和interface的区别:
inerface:声明了这是一个java的接口
@interface:表明继承了java.lang.annotation.Annotation接口,而不是声明了一个interface
@ComponentScan注解
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
(1)@ComponentScan的作用
@ComponentScan这个注解在Spring中很重要,主要就是定义扫描路径从中找出标识了需要装配的类自动装配到Spring的bean容器中。
(2)@ComponentScan的扫描路径
关于扫描路径,可以通过basePackages等属性来定制@ComponentScan自动扫描的范围,如果不指定,Spring框架会自动从声明@ComponentScan所在类的package进行扫描。所以,SpringBoot的启动类最好是放在root package下,因为默认不指定basePackages。
(3)想要被扫描到,就必须加上@ComponentScan注释
@ComponentScan会告诉Spring哪个pakages的用注解标识的类会被Spring自动扫描并装进bean容器。
例如,如果相应packages下的某个类用@Controller注解标识了,当没有一同加上@ComponentScan注解,那么,这个Controller就不会被Spring扫描到,更不会被撞倒Spring容器中。因此,这样配置的Controller毫无意义。
(4)@ComponentScan属性的作用
- basePackageClasses:扫描类所在包下的所有组件,而不是某个组件。
- excludeFilters:指定不适合组件扫描的类型。
- includerFilters:指定适合组件扫描的类型。
- lazyInit:指定是否应注册扫描的bean为lazy初始化1。
- nameGenerator:用于将在spring容器中检测到的组件命名。
- resourcePattern:控制可用于组件检测的类文件。
scopedproxy:- scopeResolver:用于决定检测到的组件的范围
- useDefaultFilters:用于决定是否自动检测类的注释
@EnableAutoConfiguraion
(1)@EnableAutoConfiguraion的作用
借助**@Import(AutoConfigurationImportSelector.class)**的支持,收集和注册特定场景相关的bean定义。
- @EnableScheduling是通过@Import将Spring调度框架相关的bean定义加载到loC容器。
- @EnableMBeanExport是通过@Import将JMX相关的bean定义加载到loC容器的。
@EnableAutoConfiguraion也是借助的@Import的帮助,将所有符合自动配置条件的bean定义加载到loC容器的。
(2)@EnableAutoConfiguraion的关键注解:@Import(AutoConfigurationImportSelector.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration
最关键的要素@Import(AutoConfigurationImportSelector.class),借助AutoConfigurationImportSelector,@EnableAutoConfiguraion可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的loC容器中。
(3)@Import(AutoConfigurationImportSelector.class)的关键函数:selectImports
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
AutoConfigurationImportSelector类最核心的函数是selectImports,其核心功能就是获取spring.factories中EnableAutoConfiguration所对应的Configurarion类列表,由@EnableAutoConfiguration注解中的exclude/excludeName参数筛选一遍,再由AutoConfigurationImportFilter类将所有实例筛选一遍,得到最终用用Import的configuration和exclusion。
@SpringBootConfiguraion
继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@bean注解标记的方法的实例纳入spring容器中,并且实例名就是方法名。
@Target注解
定义描述注解的使用范围。
ElementType表示取值,TYPE:用于描述类、接口(包括注解类型) 或enum声明。
@Retention注解
定义被它所注解的注解保留多久。
source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略
class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Documented
表明这个注释是由 javadoc记录的
@Inherited
关于java中元注解2Inherited的使用说明
类继承关系中@Inherited的作用:
类继承关系中,子类会继承父类使用的注解中被@Inherited修饰的注解
接口继承关系中@Inherited的作用:
接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被@Inherited修饰
类实现接口关系中@Inherited的作用:
类实现接口时不会继承任何接口中定义的注解