SpringApplication 实例化
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 确定应用的类型,分为SERVLET、REACTIVE。关系到 ApplicationContext、Environment 实现类的实例化
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 从 spring.factories 加载 ApplicationContextInitializer 设置到 ApplicationContext 中
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 从 spring.factories 加载 ApplicationListener 设置到 ApplicationContext 中
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 识别启动类。根据执行栈中,调用方法为 main 来确定启动类
this.mainApplicationClass = deduceMainApplicationClass();
}
private Class<?> deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
return null;
}
注册ApplicationContextInitializer
通过实例化 SpringApplication ,其构造器内部通过 SpringFactoriesLoader.loadFactoryNames 从 spring.factories 加载。
默认有:
- DelegatingApplicationContextInitializer
- SharedMetadataReaderFactoryContextInitializer
- ContextIdApplicationContextInitializer
- ConfigurationWarningsApplicationContextInitializer
- ServerPortInfoApplicationContextInitializer
- ConditionEvaluationReportLoggingListener
注册ApplicationListener
通过实例化 SpringApplication ,其构造器内部通过 SpringFactoriesLoader.loadFactoryNames 从 spring.factories 加载。
默认有:
- ConfigFileApplicationListener
- AnsiOutputApplicationListener
- LoggingApplicationListener
- ClasspathLoggingApplicationListener
- BackgroundPreinitializer
- DelegatingApplicationListener
- ParentContextCloserApplicationListener
- ClearCachesApplicationListener
- FileEncodingApplicationListener
- LiquibaseServiceLocatorApplicationListener
AnnotationConfigServletWebServerApplicationContext 实例化
注册BeanDefinitionRegistryPostProcessor
org.springframework.boot.SpringApplication#createApplicationContext,创建 AnnotationConfigServletWebServerApplicationContext 对象时,调用其构造器
public AnnotationConfigServletWebServerApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
在创建 AnnotatedBeanDefinitionReader 时,向 beanfactory 设置了 dependencyComparator = AnnotationAwareOrderComparator;autowireCandidateResolver = ContextAnnotationAutowireCandidateResolver。
默认有:
- ConfigurationClassPostProcessor
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor
- EventListenerMethodProcessor
- DefaultEventListenerFactory
回调ApplicationContextInitializer.initialize
在 org.springframework.boot.SpringApplication#applyInitializers 方法中进行回调。
作用:
- DelegatingApplicationContextInitializer,通过获取环境变量 context.initializer.classes (逗号分隔)指定的ApplicationContextInitializer实现类,并触发回调
- SharedMetadataReaderFactoryContextInitializer,注册了 CachingMetadataReaderFactoryPostProcessor
- ContextIdApplicationContextInitializer,注册了 ContextId
- ConfigurationWarningsApplicationContextInitializer注册了ConfigurationWarningsPostProcessor,输出警告
- ServerPortInfoApplicationContextInitializer,自身实现了ApplicationListener,监听WebServerInitializedEvent事件,事件触发时将服务监听端口注入到环境变量中,可以使用 @Value(“${local.server.port}”) 获取到
- ConditionEvaluationReportLoggingListener 注册了 ConditionEvaluationReportListener ,监听 ContextRefreshedEvent、ApplicationFailedEvent 事件。对容器初始化成功、失败做处理(打印日志提醒)
总结
通过默认的 ApplicationContextInitializer,向 ApplicationContext 注入了 BeanDefinitionRegistryPostProcessor:
- CachingMetadataReaderFactoryPostProcessor
- ConfigurationWarningsPostProcessor
向 ApplicationContext 设置了事件监听器:
- ServerPortInfoApplicationContextInitializer,监听WebServerInitializedEvent事件
- ConditionEvaluationReportListener,监听ContextRefreshedEvent、ApplicationFailedEvent事件
刷新ApplicationContext的主流程
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
// 应用启动各阶段事件的监听器。默认只有 spring.factories 配置的 EventPublishingRunListener
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 创建 Environment 实现类对象,Servlet 环境下为 StandardServletEnvironment
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
// 创建 ApplicationContext,其中注册了5个 BeanDefinitionRegistryPostProcessor
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
// 设置类型转换器:ApplicationConversionService
// 回调 ApplicationContextInitializer
// 将primarySource,即主配置类注册到 BeanFactory 中
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 执行 ApplicationContext refresh 操作,进行一系列的初始化操作
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 设置ClassLoader、BeanExpressionResolver、PropertyEditorRegistrar;
// 注册 BeanPostProcessor:ApplicationContextAwareProcessor、ApplicationListenerDetector
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 注册 BeanPostProcessor:WebApplicationContextServletContextAwareProcessor
// 注册 Scope(向BeanFactory.scopes属性设值):RequestScope、SessionScope
// 注册依赖:ServletRequest-RequestObjectFactory、ServletResponse-ResponseObjectFactory、HttpSession-SessionObjectFactory、WebRequest-WebRequestObjectFactory
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用BeanFactoryPostProcessor:
// 1.先调用提前实例化过的BeanDefinitionRegistryPostProcessor:CachingMetadataReaderFactoryPostProcessor、ConfigurationWarningsPostProcessor、ConfigurationClassPostProcessor
// 2.再调用注册到 BeanFactory 中的 BeanDefinitionRegistryPostProcessor(实现了 PriorityOrdered 接口的):ConfigurationClassPostProcessor,完成配置的导入,包括 spring.factories 定义的自动化配置类
// 3.再调用注册到 BeanFactory 中的 BeanDefinitionRegistryPostProcessor(实现了 Ordered 接口的):默认没有
// 4.再调用注册到 BeanFactory 中的其余的 BeanDefinitionRegistryPostProcessor:默认没有
// 5.再调用注册到 BeanFactory 中的BeanDefinitionRegistryPostProcessor.postProcessBeanFactory 方法:CachingMetadataReaderFactoryPostProcessor、ConfigurationWarningsPostProcessor、ConfigurationClassPostProcessor
// 6.再调用注册到 BeanFactory 中的BeanFactoryPostProcessor.postProcessBeanFactory 方法:PropertySourceOrderingPostProcessor
// 7.依次执行实现了PriorityOrdered、Ordered、普通BeanFactoryPostProcessor
// PropertySourcesPlaceholderConfigurer(PriorityOrdered)、EventListenerMethodProcessor、ConfigurationBeanFactoryMetadata、PreserveErrorControllerTargetClassPostProcessor(no order)
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// BeanPostProcessor的实例化并注册到beanfactory。按照PriorityOrdered、Ordered、普通、MergedBeanDefinitionPostProcessor 的顺序注册;最后注册一个 ApplicationListenerDetector
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// 实例化剩余的单例的 bean 对象(重点)
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
配置加载流程
由 invokeBeanFactoryPostProcessors 方法调用时,回调到ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry来完成配置的加载以及BeanDefinition的注册
// ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
// 处理所有配置类,包括 FullConfigure、LiteConfigure。使用 ConfigurationClassParser 进行解析。包括对 spring.factories 导入的自动化配置
processConfigBeanDefinitions(registry);
}
// ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
// 以下步骤进行一系列的 BeanDefinition 注册
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
bean实例化
@Autowire注入流程
循环依赖
配置
@Component
public class Person {
@Autowired
private Cat cat;
}
@Component
public class Cat {
@Value("${name:hehe}")
private String name;
@Autowired
private Person person;
}
流程说明
前提:cat先于person进行实例化
1、 实例化cat时,先从singletonObjects获取cat实例,此时由于未进行过实例化,singletonObjects返回null,且singletonsCurrentlyInCreation中不存在cat;因此无法获取到早期bean,返回null
2、 进入到实例化阶段时,先调用beforeSingletonCreation方法将cat添加到singletonsCurrentlyInCreation中,表示实例化中
3、 通过InstantiationStrategy策略实现类,调用默认构造器实例化bean,默认支持循环依赖的情况下,添加一个绑定beanName(cat)的ObjectFactory到singletonFactories中,移出earlySingletonObjects,放入registeredSingletons
4、 之后在执行populate设置cat属性时,BeanPostProcessor实现类AutowiredAnnotationBeanPostProcessor执行属性注入解析依赖bean,重新触发了beanfactory.getBean(“person”),进入person的实例化
5、 同样的,先从singletonObjects获取person实例,此时由于未进行过实例化,singletonObjects返回null,且singletonsCurrentlyInCreation中不存在person;因此无法获取到早期bean,返回null
6、 进入到实例化阶段时,先调用beforeSingletonCreation方法将person添加到singletonsCurrentlyInCreation中,表示实例化中
7、 通过InstantiationStrategy策略实现类,调用默认构造器实例化bean,之后BeanPostProcessor实现类AutowiredAnnotationBeanPostProcessor执行属性注入时解析依赖bean,重新触发了beanfactory.getBean(“cat”),进入cat的实例化
8、 此时,先从singletonObjects获取cat实例,此时由于未进行过实例化,singletonObjects返回null;因为第一步已经将cat放入了singletonsCurrentlyInCreation,因此尝试从 earlySingletonObjects 获取cat,但此时早期的cat实例没有放入,返回null;又因为第三步放入了绑定beanName(cat)的ObjectFactory,因此调用 getEarlyBeanReference 获取到了第三步实例化后的cat, 将cat实例放入earlySingletonObjects,并移除绑定beanName(cat)的ObjectFactory
9、 由于能获取到cat的早期bean,此时调用 getObjectForBeanInstance ,返回调用FactoryBean.getObject的对象,或者是bean对象自身(取决于bean是否为FactoryBean)
10、 返回了cat的早期bean(即未经过属性设置、初始化方法调用、BeanPostProcessor处理的bean)给到person
11、 拿到cat实例后,AutowiredAnnotationBeanPostProcessor 将它注入到person对象中,完成cat属性的依赖注入
12、 之后对person执行剩余的初始化操作,比如:Aware方法回调、BeanPostProcessor 方法回调、初始化方法调用、注册销毁回调方法等等
13、 将person移出singletonsCurrentlyInCreation、将person实例放入singletonObjects、放入registeredSingletons
14、 调用 getObjectForBeanInstance ,返回调用FactoryBean.getObject的对象,或者是bean对象自身(取决于bean是否为FactoryBean)
15、 此时cat实例拿到了依赖类对象person,注入到属性中,完成person属性的依赖注入
16、 之后对cat执行剩余的初始化操作,比如:Aware方法回调、BeanPostProcessor 方法回调、初始化方法调用、注册销毁回调方法等等
17、 调用getSingleton方法,由于singletonsCurrentlyInCreation存在cat,尝试从earlySingletonObjects获取早期的cat对象,由于第8步将cat对象放入了earlySingletonObjects中,因此获取到早期的cat对象,用于检查是否需要抛出 BeanCurrentlyInCreationException 异常
18、 将cat从singletonsCurrentlyInCreation移除,放入singletonObjects、放入registeredSingletons、移除绑定beanName(cat)的ObjectFactory、移除earlySingletonObjects
19、 此时完成了cat的实例化,并且person在这个过程中也完成了实例化,并且两者都记录到了singletonObjects