上次文章粗略写完了如何从beanFactory.getBean(beanName)
中获取一个完整的bean,以及其中bean的创建以及初始化等。在bean的创建以及BeanFactory的初始化前后会发现有不少扩展点,即xxxPostProcessor,是Spring提供的扩展模式。
那么这篇就来探讨一下Spring的后置处理器以及核心的refresh()
容器加载过程。
1、惯例,从最简单的xxxxApplicationContext
加载配置bean开始
//使用Configuration加载的话可直接使用AnnotationConfigApplicationContext进行加载
ClassPathXmlApplicationContext act = new ClassPathXmlApplicationContext("beans.xml");
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
1.1、进入构造方法,发现主要有两个方法:
-
setConfigLocations(String...configLocations)
: 解析配置文件的位置,可设置多个参数 -
refresh()
: 容器刷新方法,给IOC容器添加组件和初始化 单实例bean,后置处理机制,ApplicationEvent机制 等核心功能
1.2、下面主要记录一下refresh()
方法的主要过程,没有删除原来的英文注释。有理解错误请看英文作者注释
//相当于AbstractBeanFactory.loadBeanDefinition的增强版
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//刷新前的预准备工作,初始化了Environment,对系统属性和环境变量等属性进行提前检测,还有ApplicationEvents相关
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//刷新父容器(BeanFactory)并返回
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//为父容器做预准备工作
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 在BeanFactory初始化之后执行,在子类中可执行自定义增强
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//注册所有的BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//注册所有的BeanPostProcessor拦截bean的创建
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//初始化MessageSource
initMessageSource();
// Initialize event multicaster for this context.
//初始化容器上下文时间派发器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//在子容器中初始化特殊的bean
onRefresh();
// Check for listener beans and register them.
//注册事件监听,并使用ApplicationEventMulticaster发送事件
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//初始化所有的单实例bean
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);
}
//抛出异常则销毁所有的bean,并退出容器刷新过程
// 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();
}
}
}
如图,过程相当复杂和繁琐。我们拆分成小步骤逐个击破
- 容器刷新预准备工作
// 初始化PropertySource
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
//校验PropertySource
getEnvironment().validateRequiredProperties();
有两个重要的操作:
- 可以子类中重写并扩展初始化 :
initPropertySource()
- 检测属性是否正确的 :
validateRequiredProperties()
下面简单模拟扩展操作,重写了ClassPathXmlApplicationContext
中的inintProperty()
//自定义ApplicationContext,扩展initPropertySource方法
public class CustomClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {
public CustomClassPathXmlApplicationContext(String configLocation) throws BeansException {
super(configLocation);
}
@Override
protected void initPropertySources() {
//给环境中设置name的属性值,validateProperty()方法中会进行判断
getEnvironment().setRequiredProperties("name");
}
}
//测试类方法
public class MainTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext act = new CustomClassPathXmlApplicationContext("beans.xml");
}
}
启动测试方法,会抛出错误异常,找不到name
属性
- 刷新父容器BeanFactory,主要流程就是解析bean的配置信息,然后加载到BeanFactory里面,核心就是先获取一个
DefaultListableBeanFactory
,然后调用其loadBeanDefinitions
进行加载bean的配置信息,和第一期的XmlBeanDefinitionReader.loadBeanDefinitions
逻辑基本一致,并且这里也说明了ApplicationContext
拥有BeanFactory父容器
的所有功能。
@Override
protected final void refreshBeanFactory() throws BeansException {
//如果之前有BeanFactory则清空
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//设置重复覆盖以及可循环依赖
customizeBeanFactory(beanFactory);
//加载所有的配置信息
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
}
- 为父容器做准备工作,添加了一些常用的组件,SpEl表达式解析器,类加载器,类型转化器等等。。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置SpEl,ClassLoader,资源解析器等相关
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//设置后置处理器,该后置处理器的作用是给实现了Aware接口的实现类中的Spring组件赋值 ex : (BeanNameAware,ApplicationContextAware)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//以及忽略注入(就是说这些被忽略的接口的实现类中的属性由Spring容器提供,不能自己注入)一些Spring容器中自带的Bean,
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.
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.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
//添加AspectJ的支持
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());
}
}
- 父容器初始化之后执行的逻辑,空实现,可在子类重载自定义增强实现
- 执行
BeanFactoryPostProcessor
相关逻辑,方法申明如下,代码很多,可直接看总结
/**
* 执行BeanFactoryPostProcessor及其子类BeanFactoryRegistryPostProcessor
* @param beanFactory
* @param beanFactoryPostProcessors
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set processedBeans = new HashSet<>();
//如果是BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor会先执行其特有方法。
// 否则添加到常规BeanFactoryPostProcessor中
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List regularPostProcessors = new ArrayList<>();
List registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//如果是BeanDefinitionRegistryPostProcessor则进入
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//会优先执行postProcessBeanDefinitionRegistry
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//1.对实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//注册到总的暂存容器中
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
//2.然后对Order接口中的BeanDefinitionRegistryPostProcessor进行排序
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
//3.最后将剩余的BeanDefinitionRegistryPostProcessor进行排序
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); //执行包括配置的和硬编码(通过addBeanFactoryPostProcessor添加的)的所有BeanFactoryRegistryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); //执行硬编码中的BeanFactoryPostProcessor.postProcessBeanFactory
}
else {
// Invoke factory processors registered with the context instance.
//如果该工厂不是beanDefinitionRegistry则直接执行beanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List priorityOrderedPostProcessors = new ArrayList<>();
List orderedPostProcessorNames = new ArrayList<>();
List nonOrderedPostProcessorNames = new ArrayList<>();
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);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
总结来说有三点 :
-
BeanFactoryPostProcessor分两种
: 第一种是:BeanFactoryPostProcessor
,另外一种特殊的是 其子接口BeanFactoryRegistryPostProcessor
,子接口的加载优先级高于BeanFactoryPostProcessor
-
BeanFactoryPostProcessor
有两种来源,一种是'硬编码'也就是之前已经添加到AbstractApplicationContext.beanFactoryPostProcessors
属性中的,可以通过AbstractApplicationContext.addBeanFactoryPostProcessor
添加,另外一种是通过beanFactory
解析类型配置的来获取beanFactory.getBeanNamesForType()
,且'硬编码' 的优先级高于 ‘配置的’ - 所有的后置处理器会按照
PriorityOrdered > Order > 无序
的顺序进行执行
那么综上所述,总结源码的步骤如下
- 先执行硬编码的
BeanFactoryRegistry
的特殊方法postProcessBeanDefinitionRegistry
- 按排序顺序依次执行配置的
BeanFactoryRegistryPostProcessor
的特殊方法 - 执行所有的
BeanFactoryRegistryPostProcessor
的postProcessBeanFactory()
- 执行所有硬编码的非
BeanFactoryRegistryPostProcessor
的postProcessBeanFactory()
方法 - 执行是
BeanFactoryRegistry
但是非BeanFactoryRegistryPostProcessor
的postProcessBeanFactory()
方法 - 依次按顺序执行配置的
BeanFactoryPostProcessor
的postProcessBeanFactory()
- 最后删除元数据缓存
注册所有的
BeanPostProcessor
,同理BeanFactoryPostProcessor
,不过这里只是将所有配置中的BeanFactoryPostProcessor
添加到beanFactory中,而在创建bean实例的时候才会执行,因为这里只是注册,所以不像BeanFactoryPostProcessor
需要处理硬编码的部分。初始化国际化相关和事件派发器,这里比较简单,就是容器中没有然后会手动
new
一个添加到容器中扩展点,提供给子容器的刷新时机,比如与SpringMVC的父子容器
注册ApplicationListener,会加载容器中所有的
ApplicationListener
,并使用上面初始化过的ApplicationEventMulticaster
派发出去完成所有除后置处理相关的单实例bean的创建和初始化,主要通过getBean()方法来完成,具体可参考上一篇Bean的创建
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果是FactoryBean
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //进入创建bean的流程,后置处理器也会生效
if (bean instanceof FactoryBean) {
final FactoryBean> factory = (FactoryBean>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction)
((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
//bean创建完对象后回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
- 刷新之后的容器操作
// 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);