springboot的启动类入口
@SpringBootApplication
public class Boot01Helloworld2Application {
public static void main(String[] args) {
SpringApplication.run(Boot01Helloworld2Application.class, args);
}
}
从@SpringBootApplication注解以及SpringApplication.run进行对Springboot启动类的分析
@SpringBootApplication注解
@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
//注解的适用范围,其中TYPE用于描述类、接口(包括包注解类型)或enum声明
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
//注解的生命周期,保留到class文件中(三个生命周期)
@java.lang.annotation.Documented
// 表明这个注解应该被javadoc记录
@java.lang.annotation.Inherited
// 子类可以继承该注解
@org.springframework.boot.SpringBootConfiguration
// 继承了Configuration,表示当前是Springboot注解类
@org.springframework.boot.autoconfigure.EnableAutoConfiguration
@org.springframework.context.annotation.ComponentScan(excludeFilters = {@org.springframework.context.annotation.ComponentScan.Filter(type = org.springframework.context.annotation.FilterType.CUSTOM, classes = {org.springframework.boot.context.TypeExcludeFilter.class}), @org.springframework.context.annotation.ComponentScan.Filter(type = org.springframework.context.annotation.FilterType.CUSTOM, classes = {org.springframework.boot.autoconfigure.AutoConfigurationExcludeFilter.class})})
public @interface SpringBootApplication {
@SpringBootConfiguration分析
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
@Configuration注解上面有@Component注解,所以@Component有的功能@Configuration都有。@SpringBootConfiguration标注当前类会被扫描到IOC容器
@EnableAutoConfiguration分析
@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 org.springframework.boot.autoconfigure.AutoConfigurationPackages.Registrar; 注册当前主程序类的同级以及子级中的包中符合条件的Bean的定义(如符合@Configuration)
@Import({AutoConfigurationImportSelector.class})
将所有符合条件(工厂类的实现类)的Bean的定义都加载到IOC容器
此注解顾名思义是可以自动配置,所以应该是springboot中最为重要的注解。
在spring框架中就提供了各种以@Enable开头的注解,例如: @EnableScheduling、@EnableCaching、@EnableMBeanExport等; @EnableAutoConfiguration的理念和做事方式其实一脉相承简单概括一下就是,借助@Import的支持,收集和注册特定场景相关的bean定义。
- @EnableScheduling是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器【定时任务、时间调度任务】
- @EnableMBeanExport是通过@Import将JMX相关的bean定义加载到IoC容器【监控JVM运行时状态】
- @EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器。
从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。
可以从图中看出 AutoConfigurationImportSelector 实现了 DeferredImportSelector 从 ImportSelector继承的方法:selectImports。
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
AutoConfigurationEntry autoConfigurationEntry =getAutoConfigurationEntry(annotationMetadata);