Spring(三)ApplicationContext刷新全过程
ApplicationContext作为beanFactory的门面,他集成了beanFactory的能力并进行了扩展。
其内部有一个核心方法refresh,下面简单描述一下refresh各个方法的内容
refresh方法简介
org.springframework.context.support.AbstractApplicationContext#refresh
// 准备刷新获取bean工厂的前置操作,其内部可以扩展为添加资源,以及进行资源的校验
// 重要程度 低
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 这个就是一个很重要的方法,其内部会生成一个beanFactory,然后加载bean定义
// 不过不涉及到扩展点方面
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 像bean工厂中自动注册一些实例。
// 比如 ApplicationContextAwareProcessor,他利用了beanPostProcessor机制。完成了ApplicationContextAware的实现,并且注册了envorinment、systemProperties属性
prepareBeanFactory(beanFactory);
// 这是一个空方法,也就是模版方法,等待子类覆盖,对beanFactory进行改造
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 这个方法是用来加载beanFactory的processor的,很重要,后面描述
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册beanPostProcessor,也很重要
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 国际化消息这一块,用到看下就行
initMessageSource();
// Initialize event multicaster for this context.
// spring利用监听者模式搞了个消息的监听和广播,用到看下就行
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 模版方法,空的
onRefresh();
// Check for listener beans and register them.
// 这还是spring的广播消息的内容,属于注册监听者这一块的
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 内部有两个内容很重要 1、冻结bean定义的更改 2、加载单例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 加载完成了,当然要发个广播消息了。另外还搞了个spring的声明周期,此处会调用周期的onRefresh方法。
finishRefresh();
refresh内部方法抽要介绍
prepareBeanFactory方法
其内部有一个我认为比较重要的方法,和applicationContext的aware扩展点有关,具体调用如下。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
其ApplicationContextAwareProcessor实现了BeanPostProcessor接口,并重写了postProcessBeforeInitialization方法
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
据之前介绍的beanPostProcessor机制介绍,在完成实例化之后,初始化之前会调用postProcessBeforeInitialization方法,此时就判断该bean如果实现了对应的aware接口,则会把对应的内容传递进去。
invokeBeanFactoryPostProcessors方法
这个地方也是ApplicationContext提供的一个核心扩展点,针对BeanDefinitionRegistryPostProcessor以及BeanFactoryPostProcessor。其内部关于两个扩展点的实现基本一致,下面简单的看下是如何按优先级加载BeanFactoryPostProcessor以及调用的
// 1、获取所有的BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 预先准备好三类bean,高优先级的,优先的,没有优先级的
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
// 编辑所有的BeanFactoryPostProcessor,分类
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 按照优先级进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 对priorityOrderedPostProcessors进行调用
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 获取优先的进行排序调用
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 获取没有优先级的无序调用
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
其内部的逻辑顺序如上述代码备注一样
1、获取所有的BeanFactoryPostProcessor
2、分为三类高优先级的,优先的,无优先级的
3、高优先级(实现PriorityOrdered接口)的排序调用
4、优先的(实现Ordered接口)排序调用
5、无优先级的遍历调用
registerBeanPostProcessors方法
和上述代码基本一致。
1、找到所有的BeanPostProcessor
2、分为三类高优先级的,优先的,无优先级的
3、高优先级(实现PriorityOrdered接口)的注册到BeanPostProcessor集合
4、优先的(实现Ordered接口)注册到BeanPostProcessor集合
5、无优先级的注册到BeanPostProcessor集合