spring容器加载分析 二容器刷新
容器刷新是容器加载的核心方法,包括:BeanFactory的设置、Configuration类解析、Bean实例化、属性和依赖注入、事件监听器注册。都是由此方法展开的。
本着先理解脉络在搞懂细节的原则,为不干扰对容器刷新过程理解,对Configuration类解析部分和Bean实例化部分只做了总结性说明,后续会专门分析。
容器刷新方法在AbstractApplicationContext类中实现,所以不管是ClassPathXmlApplicationContext、AnnotationConfigApplicationContext、 AnnotationConfigWebApplicationContext等各种具体的容器都是这个方法。
容器刷新方法:
public void refresh() throws BeansException, IllegalStateException {
// refresh过程只能一个线程处理,不允许并发执行。
synchronized (this.startupShutdownMonitor) {
prepareRefresh();// step 1
// 获取BeanFactory,容器初始化的时候已实例化
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory); // step 2
try {
postProcessBeanFactory(beanFactory); // step 3
invokeBeanFactoryPostProcessors(beanFactory); // step 4
registerBeanPostProcessors(beanFactory);// step 5
initMessageSource();// step 6
initApplicationEventMulticaster();// step 7
onRefresh();// step8
registerListeners();// step 9
finishBeanFactoryInitialization(beanFactory);// step 10
finishRefresh();// step 11
} 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 {
resetCommonCaches();
}
}
}
step 1 prepareRefresh()
在刷新容器操作之前做些准备的工作,包括:
1、设置Spring容器的启动时间,撤销关闭状态,开启活跃状态。
2、初始化属性源信息(Property)。
3、验证环境信息里一些必须存在的属性。
代码较为简单没贴源码,请自行查看。
step 2 prepareBeanFactory()
beanFactory预处理
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置beanFactory的ClassLoader为当前的ClassLoader
beanFactory.setBeanClassLoader(getClassLoader());
// 设置表达式解析器(解析bean定义中的一些表达式)
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加属性编辑注册器(注册属性编辑器),属性编辑器实际上是属性的类型转换器,
// 因为bean的属性配置都是字符串类型的 实例化的时候要将这些属性转换为实际类型
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加BeanPostProcessor(Bean后置处理器):ApplicationContextAwareProcessor
// 在BEAN初始化之前,调用ApplicationContextAwareProcessor的postProcessBeforeInitialization
// 处理所有的Aware接口,进行如下操作:
// 如果bean实现了EnvironmentAware接口,调用bean.setEnvironment
// 如果bean实现了EmbeddedValueResolverAware接口,调用bean.setEmbeddedValueResolver
// 如果bean实现了ResourceLoaderAware接口,调用bean.setResourceLoader
// 如果bean实现了ApplicationEventPublisherAware接口,调用bean.setApplicationEventPublisher
// 如果bean实现了MessageSourceAware接口,调用bean.setMessageSource
// 如果bean实现了ApplicationContextAware接口,调用bean.setApplicationContext
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 取消ResourceLoaderAware
// 、ApplicationEventPublisherAware
// 、MessageSourceAware
// 、ApplicationContextAware
// 、EnvironmentAware这5个接口的自动注入
// 因为ApplicationContextAwareProcessor把这5个接口的实现工作做了
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.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加BeanPostProcessor(后置处理器):ApplicationListenerDetector
// 在Bean初始化后检查是否实现了ApplicationListener接口,
// 是则加入当前的applicationContext的applicationListeners列表
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 检查容器中是否包含名称为loadTimeWeaver的bean,实际上是增加Aspectj的支持
// AspectJ采用编译期织入、类加载期织入两种方式进行切面的织入
// 类加载期织入简称为LTW(Load Time Weaving),通过特殊的类加载器来代理JVM默认的类加载器实现
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
// 添加BEAN后置处理器:LoadTimeWeaverAwareProcessor
// 在BEAN初始化之前检查BEAN是否实现了LoadTimeWeaverAware接口,
// 如果是,则进行加载时织入,即静态代理。
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 注入一些其它信息的bean,比如environment、systemProperties等
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());
}
}
对beanFactory进行了如下操作:
1、设置了ClassLoader
2、设置了表达式解析器
3、设置了属性编辑器
4、添加了一个BeanPostProcessor实现:ApplicationContextAwareProcessor,它是用来处理并回调实现了各种Aware接口的Bean,比如获取ApplicationContext的ApplicationContextAware接口。
5、取消了一个工作接口,添加了一些特殊的Bean
6、添加BeanPostProcessor实现:ApplicationListenerDetector,它是用来将实现了ApplicationListener接口的Bean添加到容器的监听器列表。
7、如果beanFactory中包含名称为loadTimeWeaver的Bean,则添加BeanPostProcessor实现:LoadTimeWeaverAwareProcessor,它是用来处理AspectJ类加载期织入LTW(Load Time Weaving)的。
8、注入environment、systemProperties、systemEnvironment三个Bean
step 3 postProcessBeanFactory()
beanFactory后置处理,是一个模板方法,交由不同的ApplicationContext实现自己处理逻辑,做一些特有的操作。
比如GenericWebApplicationContext容器会在BeanFactory中添加ServletContextAwareProcessor用于处理ServletContextAware类型的bean初始化的时候调用setServletContext或者setServletConfig方法。
step 4 invokeBeanFactoryPostProcessors()
调用BeanFactoryPostProcessor
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 调用BeanFactoryPostProcessors
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 再次检查使用存在LoadTimeWeaverBean,如果进行LWT的处理
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
getBeanFactoryPostProcessors()是获取直接添加到容器中的BeanFactoryPostProcessor,如下面这样添加的:
public static void main(String[] args) {
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(StartupConfig.class);
context.addBeanFactoryPostProcessor(new TestBeanFactoryPostProcessor());
}
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法中的处理逻辑是,查找到容器中注册的BeanFactoryPostProcessors连同直接添加的BeanFactoryPostProcessors进行排序,排序的依据的@Order注解,然后依次调用,限于篇幅没贴源码,请自行查看。
在容器初始化时注册到容器中注册的ConfigurationClassPostProcessor会被排到最前面,它的作用是解析包含JavaConfig注解的类或者被@Configuration注解的类,称之为配置类ConfigurationClass。
一些BeanFactoryPostProcessor实例是通过ConfigurationClass注册的,如果不优先执行ConfigurationClassPostProcessor这些Processor实例就不会被注册到容器,也就得不到执行。
ConfigurationClassPostProcessor中使用ConfigurationClassParser来解析ConfigurationClass中的配置,解析的过程:
1、处理@PropertySources注解,解析属性文件
2、处理@ComponentScan注解,通过ComponentScanAnnotationParser扫描Bean定义
3、处理@Import注解,递归解析Import进来的Bean定义
4、处理@Bean注解,获取被@Bean注解修饰的方法,然后添加到配置类的beanMethods属性中
解析完毕使用ClassBeanDefinitionReader来注册解析出来的BeanDefinition。
因为解析过程复杂,为了不影响对容器刷新过程脉络的理解,没有在此分析,详细解析和注册过程请参见:spring容器加载分析 三Configuration类解析
step 5 registerBeanPostProcessors()
注册BeanPostProcessor,从Spring容器中找出的实现了BeanPostProcessor接口的Bean,并设置到BeanFactory中,之后bean被实例化的时候会调用这些BeanPostProcessor。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//从beng工厂中找出所有BeanPostProcessor类型的实例
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// BeanPostProcessorChecker是一个普通的打印信息
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
//先找出实现了PriorityOrdered接口的BeanPostProcessor并排序后加到BeanFactory的BeanPostProcessor集合中
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//找出实现了Ordered接口的BeanPostProcessor并排序后加到BeanFactory的BeanPostProcessor集合中
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 第一步, 注册所有实现了PriorityOrdered接口的BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 第二部, 注册所有实现了Ordered接口的BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 第三步, 注册所有无序的BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 第四步, 注册所有MergedBeanDefinitionPostProcessor类型的BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 添加ApplicationListener探测器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
step 6 initMessageSource()
初始化国际化(I18N)信息
step 7 initApplicationEventMulticaster();
初始化Spring事件广播器用于事件的发布,这个事件广播器允许用户自己定义。
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果有用户自定义的事件广播器(名称为:applicationEventMulticaster的bean)
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
// 如果有用户没有自定义的事件广播器(名称为:applicationEventMulticaster的bean),
// 使用系统默认的SimpleApplicationEventMulticaster
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
通常情况很少有用户自定义事件广播的,SimpleApplicationEventMulticaster的核心功能是根据事件和事件类型从容器中找出符合的事件监听器,依次调用。
@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
invokeListener(listener, event);
}
}
}
step 8 onRefresh()
这是一个模板方法,交由不同的子类实现处理自己的逻辑。比如web程序的容器AnnotationConfigEmbeddedWebApplicationContext中会调用createEmbeddedServletContainer方法去创建内置的Servlet容器。
step 9 registerListeners()
注册事件监听器,把直接添加到容器内的事件监听器和beanFactory中的事件监听器都添加的事件广播器ApplicationEventMulticaster中。
protected void registerListeners() {
// 直接添加到容器中的事件监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 从beanFactory中获取所有实现了ApplicationListener接口的事件监听器
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 如果存在earlyApplicationEvents,直接广播出去
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
step 10 finishBeanFactoryInitialization()
初始化非延迟加载的单例Bean, 实例化BeanFactory中已经被注册但是未实例化的所有实例(@Lazy注解的Bean不在此实例化)。
invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。实例化的过程各种BeanPostProcessor开始起作用。
实例化的过程也是巨复杂的过程,为了不影响对容器刷新过程脉络的理解,没有在此分析,详细解析和注册过程请参见:spring容器加载分析 四Bean实例化
step 11 finishRefresh()
refresh结束之前需要做善后工作。包括生命周期组件LifecycleProcessor的初始化和调用、事件发布、JMX组件的处理等。
protected void finishRefresh() {
// 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()
初始化容器的LifecycleProcessor。
Lifecycle接口为Bean提供了生命周期的回调方法,会在ApplicationContext启动(start)和停止(stop)的时候通知Bean做出响应。
它有两个扩展接口LifecycleProcessor和SmartLifecycle,LifecycleProcessor增加了onRefresh和onClose另个方法分别对应ApplicationContext的刷新和关闭。
而SmartLifecycle接口可以通过getPhase()方法来控制Bean启动和销毁的顺序,getPhase返回的数字越小则Bean启动的越早销毁的越晚,getPhase返回的数字越大则Bean启动的越晚销毁的越早。
容器中对Lifecycle接口的处理是委托给LifecycleProcessor实现的,通常都是DefaultLifecycleProcessor ,LifecycleProcessor初始化过程:
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果beanFactory包含名称为lifecycleProcessor的Bean,直接获取
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
}
else {// 使用默认的lifecycleProcessor
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
}
}
2、getLifecycleProcessor().onRefresh()
DefaultLifecycleProcessor 会从beanFactory中查找所有实现了LifecycleProcessor接口的Bean,然后一次调用其onRefresh方法。
3、publishEvent(new ContextRefreshedEvent(this))
广播ContextRefreshedEvent事件,通过事件广播器ApplicationEventMulticaster向所有监听了ContextRefreshedEvent事件的监听器进行通知。
4、LiveBeansView.registerApplicationContext(this)
向MBeanServer注册LiveBeansView,可以通过JMX来监控此ApplicationContext。
至此容器就已经全部加载完毕,进入工作状态。
码字不易,转载请保留原文连接https://www.jianshu.com/p/5836d3d6dc72