Bean的生命周期:
InstantiationAwareBeanPostProcessors前后置处理方法,在Bean实例化之前被调用,允许返回一个实例来替代默认的实例化过程。如果返回非空实例,则Spring将跳过默认的实例化步骤-》若是返回非空直接返回-》若为空则执行doCreateBean-》首先创建实例-》进行属性注入-》调initializeBean-》首先判断是否实现了aware接口的方法进行相应的资源注入-》执行beanpostprocessor的前置方法-》进入invokeInitMethods判断是否实现了initializingbean,若有则执行afterPropertiesSet方法-》后面在执行自定义的初始化方法-》beanpostprocess的后置方法-》容器销毁时执行deposiable接口的销毁方法和自定义的销毁方法
前言
前两篇文章分析了Spring XML和注解的解析原理,并将其封装为BeanDefinition对象存放到IOC容器中,而这些只是refresh方法中的其中一个步骤——obtainFreshBeanFactory,接下来就将围绕着这些BeanDefinition对象进行一系列的处理,如BeanDefinitionRegistryPostProcessor对象方法的调用、BeanFactoryPostProcessor对象方法的调用以及Bean实例的创建都离不开这些BeanDefinition对象。下面就来看看Spring是如何处理这些对象的。
正文
环境准备
首先我们先回忆下refresh方法:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//为容器初始化做准备
prepareRefresh();
// 解析xml和注解
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 给BeanFacory设置属性值以及添加一些处理器,即准备Spring的上下文环境
prepareBeanFactory(beanFactory);
try {
// 由子类实现对BeanFacoty的一些后置处理
postProcessBeanFactory(beanFactory);
/*
* BeanDefinitionRegistryPostProcessor
* BeanFactoryPostProcessor
* 完成对这两个接口的调用
* */
invokeBeanFactoryPostProcessors(beanFactory);
/*
* 把实现了BeanPostProcessor接口的类实例化,并且加入到BeanFactory中
* */
registerBeanPostProcessors(beanFactory);
/*
* 国际化
* */
initMessageSource();
//初始化事件管理类
initApplicationEventMulticaster();
//这个方法着重理解模板设计模式,因为在springboot中,这个方法是用来做内嵌tomcat启动的
onRefresh();
/*
* 往事件管理类中注册事件类
* */
registerListeners();
/*
* 1、bean实例化过程
* 2、依赖注入
* 3、注解支持
* 4、BeanPostProcessor的执行
* 5、Aop的入口
*
* */
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
} finally {
resetCommonCaches();
}
}
}
prepareBeanFactory和postProcessBeanFactory没什么复杂的,关注一下里面设置了哪些值,添加了哪些对象就行,这些东西在后面的流程中会起到作用。尤其是postProcessBeanFactory,这是一个模板方法,在其子类AbstractRefreshableWebApplicationContext中设置了两个重要的标识:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 主要看着里面
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
分别将hasInstantiationAwareBeanPostProcessors、hasDestructionAwareBeanPostProcessors属性都设置成了true,可以猜一下它们有什么作用。
两个重要的Processor
在将上下文环境设置完成后,就是通过invokeBeanFactoryPostProcessors方法完成对BeanDefinitionRegistry以及BeanFactory的后置处理器的处理和调用,也就是依次调用BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的实现类。我们可以通过实现这两个接口在在BeanDefinition注册完成后,对象实例化之前对容器中的BeanDefinition进行动态的增删查改,比如Spring中@Configuration注解的解析就是在这个过程中实现的。我们先来了解一下Spring内置的Processor实现有哪些:
整个体系需要有个大概的印象,其中重点关注ConfigurationClassPostProcessor类,该类就是完成对@Configuration、@Bean等注解的解析注册,这一块的源码这里暂时不分析。继续开始的流程,进入到invokeBeanFactoryPostProcessors方法:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// getBeanFactoryPostProcessors方法一般是获取不到值的,除非我们手动调用addBeanFactoryPostProcessor方法添加进去,
// 换言之我们可以通过注解@Component或是手动调用addBeanFactoryPostProcessor方法来注入BeanFactoryPostProcessors对象
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
省略......
}
这里面 通过委托模式调用PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法,并传入了BeanFactory和Processors对象,但需要注意getBeanFactoryPostProcessors方法不是获取通过xml配置和Component注解注册到容器中的Processor对象,而是获取通过调用AbstractApplicationContext.addBeanFactoryPostProcessor方法添加的类,换言之我们实现了Processor接口后可以不在类上添加@Component,直接调用addBeanFactoryPostProcessor方法即可,但需要注意,这种方式并没有对应的BeanDefinition类,添加的对象也不存在于IOC容器中。
继续进入invokeBeanFactoryPostProcessors方法:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 优先处理通过addBeanFactoryPostProcessor方法添加的BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 优先处理BeanDefinitionRegistryPostProcessor对象
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//获取实现了BeanDefinitionRegistryPostProcessor接口的所有类的BeanDefinition对象的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//判断是否实现了排序接口 PriorityOrdered
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//调用过程
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//判断是否是实现的Ordered接口
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryPro