目录
一、AnnotationConfigApplicationContext
2.6 invokeBeanFactoryPostProcessors
2.7 registerBeanPostProcessors
2.9 initApplicationEventMulticaster
2.12 finishBeanFactoryInitialization
以注解版本分析Spring容器创建流程
一、AnnotationConfigApplicationContext
利用AnnotationConfigApplicationContext创建ioc容器,可将自定义配置类(例如标识@Configuration注解)来导入组件。
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestLifeCycleConfig.class);
因为AnnotationConfigApplicationContext继承GenericApplicationContext,若是没指定beanFactory容器对象,则在GenericApplicationContext的构造函数中会默认创建一个类型为DefaultListableBeanFactory的容器对象,通过register方法将自定义的配置类注册到容器中,接着通过refresh方法刷新容器。
二、refresh()
ioc容器创建环境对象、加载配置文件、注册beanFactory、bean后置处理器、监听器、创建单实例非延迟加载组件等功能是通过AbstractApplicationContext的refresh方法完成。
在refresh方法中,先将该方法进行同步处理,目的是防止多线程同时刷新容器。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//为刷新容器做准备,例如设置closed、active属性、加载配置文件、创建环境对象等
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//获取beanFactory容器对象
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//设置容器的类加载器、添加一些bean后置处理器等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//创建实现BeanFactoryPostProcessor接口的实现类并运行对应实现接口方法
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//创建实现BeanPostProcessor接口的实现类并将对象加到容器的BeanPostProcessor集合中,在后续容器创建初始化组件对象时,调用对应方法
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();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化容器中剩余的非延迟加载的单实例组件
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//完成容器刷新,清除缓存和发布容器刷新完成事件等
finishRefresh();
}
catch (BeansException ex) {
...
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
2.1 prepareRefresh
prepareRefresh方法主要是在容器刷新前准备一些环境,例如设置closed、active属性,加载配置文件、创建环境对象等。
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
//加载配置文件,例如web环境下的容器对象通过该方法事先加载配置文件
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
//校验配置文件
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
//为事件监听器做一些准备
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2.3 obtainFreshBeanFactory
obtainFreshBeanFactory方法告诉子容器(子类)刷新容器后返回容器对象,
refreshBeanFactory方法有2个子类实现了不同的功能,
1、GenericApplicationContext: 例如设置序列号id等,
2、AbstractRefreshableApplicationContext:如果存在容器对象,则销毁先前的容器,重新创建一个新的DefaultListableBeanFactory类型的容器对象,然后设置序列号id等,通过loadBeanDefinitions方法扫描xml配置文件,加载beanDefinition到容器中。
2.4 prepareBeanFactory
prepareBeanFactory方法是为在上下文中使用beanFactory容器对象做一些提前准备,例如设置类加载器、设置忽略依赖注入接口、设置可依赖注入的组件、添加部分Bean后置处理器等。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置类加载器、组件表达式解析器
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//添加bean后置处理器,ApplicationContextAwareProcessor后置处理器可处理实现EnvironmentAware等xxAware接口的实现类,调用setXX方法将对应组件对象传给实现类
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置不可直接依赖注入的接口类
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
//设置可直接通过@Autowired等依赖注入的组件
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
//添加解析事件监听器的bean后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
//注册环境对象
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
2.5 postProcessBeanFactory
postProcessBeanFactory方法允许AbstractApplicationContext的子类重写该方法为容器做一些后置处理,例如GenericWebApplicationContext,而DefaultListableBeanFactory没重写该方法,还是跟父类一样为空方法
2.6 invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors方法是用来创建实现BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor接口的实现类对象并运行对应的方法。
1)先创建BeanDefinitionRegistryPostProcessor接口的实现类
按照优先级顺序,
1、创建实现PriorityOrdered接口的实现类对象并调用postProcessBeanDefinition方法
2、创建实现Ordered接口的实现类对象并调用postProcessBeanDefinition方法
3、创建没实现PriorityOrdered、Ordered接口的实现类对象并调用postProcessBeanDefinition方法
2)先创建BeanFactoryPostProcessor接口的实现类
按照优先级顺序,
1、创建实现PriorityOrdered接口的实现类对象并调用postProcessBeanFactory方法
2、创建实现Ordered接口的实现类对象并调用postProcessBeanFactory方法
3、创建没实现PriorityOrdered、Ordered接口的实现类对象并调用postProcessBeanFactory方法
BeanDefinitionRegistryPostProcessor(继承BeanFactoryPostProcessor):可自定义向容器添加beanDefinition。
BeanFactoryPostProcessor:可获取容器的beanDefinition集合进行操作。
例如容器内置的ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,该类通过postProcessBeanDefinitionRegistry方法扫描容器的配置类,解析配置类得到beanDefinition组件并注册到容器中。
参考Spring-分析BeanFactoryPostProcessor后置处理器_Just-Today的博客-CSDN博客
2.7 registerBeanPostProcessors
registerBeanPostProcessors方法主要是创建实现了BeanPostProcessor接口的实现类对象并加到容器的BeanPostProcessor集合中,在后续容器创建初始化组件时遍历BeanPostProcessor集合调用对应后置处理方法。
按照优先级顺序
1、创建实现PriorityOrdered接口的实现类对象
2、创建实现Ordered接口的实现类对象
3、创建没实现PriorityOrdered、Ordered接口的实现类对象
不同的BeanPostProcessor接口,执行顺序不同
1、InstantiationAwareBeanPostProcessor:在创建组件对象之前,给bean后置处理器一个机会,返回该组件的代理对象
2、MergedBeanDefinitionPostProcessor:在组件创建之后,可对RootBeanDefinition进行操作
参考什么是MergedBeanDefinition?_jiangjun316的博客-CSDN博客
3、BeanPostProcessor:在组件初始化前后
4、DestructionAwareBeanPostProcessor:在组件销毁之前
参考
分析-BeanPostProceesor后置处理器_Just-Today的博客-CSDN博客
2.8 initMessageSource
初始化国际化配置,
1、先判断容器中是否有beanName为messageSource的MessageSource接口实现类对象,
若是有,进行一些设置,例如parentMessageSource属性,
2、若是没有,则默认创建一个类型为DelegatingMessageSource的对象,并添加到容器的单实例集合中,组件名称为messageSource,设置parentMessageSource属性。
2.9 initApplicationEventMulticaster
初始化事件多发器,
1、先判断容器中是否有beanName为applicationEventMulticaster的ApplicationEventMulticaster接口实现类对象,
若是有,则将其对象赋值到容器的applicationEventMulticaster属性,
2、若是没有,则默认创建一个类型为SimpleApplicationEventMulticaster的对象,并添加到容器的单实例集合中,组件名称为applicationEventMulticaster。
可参考
分析Spring-ApplicationListener监听器_Just-Today的博客-CSDN博客
2.10 onRefresh
子类可重写该方法初始化一些特殊的组件对象。
2.11 registerListeners
注册事件监听器到容器的事件多播器中。
可参考
分析Spring-ApplicationListener监听器_Just-Today的博客-CSDN博客
2.12 finishBeanFactoryInitialization
实例化容器中剩余的非延迟加载的单实例组件。
可参考
spring-bean生命周期_Just-Today的博客-CSDN博客的4、创建组件对象(单例)章节
2.13 finishRefresh
完成容器刷新,清除缓存和发布容器刷新完成事件等。
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
//清除缓存
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
//发布事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
1、initLifecycleProcessor方法先判断容器中是否有beanName为lifecycleProcessor的LifecycleProcessor接口实现类对象,若是有,则将其对象赋值到容器的lifecycleProcessor属性,我们可以实现LifecycleProcessor接口的onRefresh、onClose方法,在后面会调用。
2、若是没有,则默认创建一个类型为DefaultLifecycleProcessor的对象,并添加到容器的单实例集合中,组件名称为lifecycleProcessor。
3、getLifecycleProcessor().onRefresh()找到容器的LifecycleProcessor接口实现类对象,调用onRefresh方法。
4、发布ContextRefreshedEvent事件