Springboot启动过程
元注解
元标签有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。
FactoryBean getObject
1. 静态注入
2. 动态引入
基于ImportSelector接口实现
3. 基于ImportBeanDefinition
4. spring.factories
@conditional 加载到容器的条件
第一个决定要加载的类型, 第二个决定是否加载?
扩展下. 其实springCloud组件 很多用到@Import @Conditional , 还有些select等, 顺藤摸瓜 我简答列列举几个:
@SpringBootApplication--@EnableAutoConfiguration
@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 {}
@Import(AutoConfigurationImportSelector.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
重点说下Selector:
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {}
最顶层继承了ImportSelector 和 Aware接口:
public interface ImportSelector {
}
protected ListString getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
ListString configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
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;
}
protected Class? getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
其实最终是寻找EnableAutoConfiguration对应的类组合, EnableAutoConfiguration来自package org.springframework.boot.autoconfigure;
所以最终初始化时, 是加载了spring-boot-autoconfigure里面的spring.factories的内容, 简单列举出现:
说明下:
SpringFactoriesLoader属于Spring框架私有的一种扩
展方案,其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。
public final class SpringFactoriesLoader {
}
spring boot启动流程
入口是一个main方法,这个main方法里面new一个SpringApplication对象,传入bean源,就是注解了SpringBootApplication 的那个类,调用run方法。
spring boot启动流程分为两部分 一部分是准备阶段,一部分是运行阶段
准备阶段主要有这么几步:
1、配置bean的源,就是bean的来源,就是注解了SpringBootApplication的那个类。
2、推断,推断应用类型,有webflux,webservlet,none
推断主类,这个是通过线程堆栈实现,构造一个运行时异常,找异常堆栈里面找mian所在的那个类。
3、加载上下文初始化器 在这里可以调整applicationcontext
4、加载应用事件监听器 这两个东西都是在mete-info/spring.factories文件里面。
运行阶段,就是调用run方法
先是加载SpringApplication运行时监听器,SpringApplicationRunListeners,默认只有一个EventPublishingRunListener,需要传入准备阶段加载的listeners,在这个地方调用一个广播器广播事件。
然后会根据推断类型,创建一个ApplicationContext,ConfigurableApplicationContext
对这个context初始化,refresh方法
最后会返回这个context。
自动装配:
1、激活自动配置, EnableAutoConfiguration
2、实现自动配置(注解装配,模式装配,条件装配)配置bean
3、将这个配置配置到spring.factories文件里面去
springboot启动流程 简单流程来了
当我们运行SpringApplication的main方法时,调用静态方法run()首先是实例化,SpringApplication初始化的时候主要做主要做三件事:
1、根据classpath下是否存在(ConfigurableWebApplicationContext)判断是否要启动一个web applicationContext。
2、SpringFactoriesInstances加载classpath下所有可用的ApplicationContextInitializer
3、SpringFactoriesInstances加载classpath下所有可用的ApplicationListener