在此之前写了2篇博客,分析了springIOC容器初始化的过程和spring Bean依赖注入的过程,spring在初始化时还做了很多事情,比如注册执行BeanFactoryPostProcessor,注册
BeanPostPorcessor。本篇文章主要就是为了分析这俩点,还有bean依赖注入过程中Bean的初始化。
用过spring的都知道,在定义bean的时候可以指定init-method属性,让bean实例化之后,根据此方法进行初始化。其实除了指定init-method方法,还有其它的方式在bean初始化前
后进行处理。个人知道的有实现InitializingBean,BeanFactoryPostProcessor,BeanPostProcessor有这三种。当然实现Aware接口也可以,但是官方文档中说的
Spring提供了一系列的Aware接口使得bean可以从容器获取需要的资源,个人觉得不适合来控制bean的初始化。
InitializingBean:bean实现此接口后bean在实例化之后会调用afterPropertiesSet()方法。
BeanFactoryPostProcessor:在spring容器加载了bean的定义文件,将其解析成BeanDefinition之后,在bean实例化之前执行的。我们在通过spring配置数据源时,
一般把数据源的具体信息写在一个配置文件中,然后用${url}的形式注入进去。将${url}替换成我们配置里的值就是通过Spring内置的一个BeanFactoryPost,
PropertyPlaceholderConfigurer来实现的。
BeanPostProcessor:定义了俩个方法。postProcessBeforeInitialization()方法在初始化之前执行,postProcessAfterInitialization在初始化之后执行。
1.javaBean
package vo;
import org.springframework.beans.factory.InitializingBean;
public class User implements InitializingBean {
private String name;
public void init() {
System.out.println("调用了init---" + "原来的name为" + name + "name设置为init");
name = "init";
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("调用了afterPropertiesSet---" + "原来的name为" + name + "name设置为afterPropertiesSet");
name = "afterPropertiesSet";
}
@Override
public String toString() {
return "User [name=" + name + "]";
}
}
package vo;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.TypedStringValue;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition bd = beanFactory.getBeanDefinition("user");
MutablePropertyValues mpv = bd.getPropertyValues();
if (mpv.contains("name")) {
String oldName=((TypedStringValue) mpv.getPropertyValue("name").getValue()).getValue();
System.out.println("调用了MyBeanFactoryPostProcessor---"+"原来的name为"+oldName+"将name设置为:MyBeanFactoryPostProcessor");
mpv.addPropertyValue("name", "MyBeanFactoryPostProcessor");
}
}
}
package vo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("调用了postProcessBeforeInitialization---------beanName:"+beanName+"---bean:"+bean+"将name设置为MyBeanPostProcessor-Befor");
if("user".equals(beanName)){
User user = (User) bean;
user.setName("MyBeanPostProcessor-Before");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("调用了postProcessAfterInitialization----------beanName:"+beanName+"---bean:"+bean+"将name设置为MyBeanPostProcessor-After");
if("user".equals(beanName)){
User user = (User) bean;
user.setName("MyBeanPostProcessor-After");
}
return bean;
}
}
package vo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Services {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
User u = (User) ctx.getBean("user");
System.out.println("用户拿到的name:"+u.getName());
}
}
调用了MyBeanFactoryPostProcessor---原来的name为czy将name设置为:MyBeanFactoryPostProcessor
调用了postProcessBeforeInitialization---------beanName:user---bean:User [name=MyBeanFactoryPostProcessor]将name设置为MyBeanPostProcessor-Befor
调用了afterPropertiesSet---原来的name为MyBeanPostProcessor-Beforename设置为afterPropertiesSet
调用了init---原来的name为afterPropertiesSetname设置为init
调用了postProcessAfterInitialization----------beanName:user---bean:User [name=init]将name设置为MyBeanPostProcessor-After
用户拿到的name:MyBeanPostProcessor-After
7.分析结果
3)执行InitializingBean接口的afterPropertiesSet()
5)执行BeanPostProcessor的postProcessAfterInitialization方法。
可以把断点打在getBean()方法上,会发现控制台已经输出了上面的第一句化,说明BeanFactoryPostProcessor是在Bean实例化之前执行,BeanFactoryPostProcessor在spring加载了bean的定义文件在调试的时候可以。从最终的输出可以看出整个执行顺序如下:
1)执行BeanFactoryPostProcessor
2)执行BeanPostProcessor的postProcessBeforeInitialization方法。
4)执行init-method属性指定的方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1. 刷新前的准备工作
prepareRefresh();
//2. 关闭释放旧的beanFactory创建新的beanFactory,读取配置文件等
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3. 对beanFactory进行一些基本的初始化
prepareBeanFactory(beanFactory);
try {
//4. 下面两行主要用户扩展,处理所有已注册的BeanFactoryPostProcessor,实现在已经加载配置但未初始化bean时对配置进行修改
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
//5. 处理所有已注册的BeanPostProcessor,主要用于扩展,实现bean初始化前后的一些定制操作
registerBeanPostProcessors(beanFactory);
//6. 初始化消息源bean
initMessageSource();
//7. 初始化事件监听器集,也有人叫事件监听器的注册表,所有的事件监听器都在这个bean里进行管理
initApplicationEventMulticaster();
//8. 主要用于扩展,实现一些特殊bean的初始化,时间点是类似消息源事件监听器集等特殊bean初始化后,普通的bean初始化前
onRefresh();
//9. 注册监听器
registerListeners();
//10. 初始化其余的非延迟加载的单例bean
finishBeanFactoryInitialization(beanFactory);
//11. 刷新完成调用LifecycleProcessor的onRefresh方法,并且发布ContextRefreshedEvent事件
finishRefresh();
} catch (BeansException ex) {
// 销毁已经创建的单例bean
destroyBeans();
// 重新设置active标记
cancelRefresh(ex);
throw ex;
}
}
}
其中第2步就是spring容器加载了bean的定义文件,将其解析成BeanDefinition,可以参考我之前的博文Spring源码解读 IOC容器初始化,第4步就是执行BeanFactoryPostProcessor,第5步是向BeanFactory注入BeanPostProcessor,BeanPostProcessor方法是在getBean()触发的,如果不是延时初始化,在第11步就执行了,如果是在用户手工调用getBean()时触发。这也是为什么我在配置文件中将lazy-init设置成true的原因。
我们先看一下第4步的源码,我在调试的时候发现postProcessBeanFactory()是个空实现,在此不追究,主要看一下invokeBeanFactoryPostProcessors()方法
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
发现是通过PostProcessorRegistrationDelegate来执行的,我们在看一下PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()方法:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
Set processedBeans = new HashSet();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List regularPostProcessors = new LinkedList();
List registryPostProcessors =
new LinkedList();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
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.
//获取BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
List priorityOrderedPostProcessors = new ArrayList();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//根据优先级排序
OrderComparator.sort(priorityOrderedPostProcessors);
registryPostProcessors.addAll(priorityOrderedPostProcessors);
//按照排序顺序循环执行
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List orderedPostProcessors = new ArrayList();
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
OrderComparator.sort(orderedPostProcessors);
registryPostProcessors.addAll(orderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
}
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
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.
OrderComparator.sort(priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
OrderComparator.sort(orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List nonOrderedPostProcessors = new ArrayList();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}
整个方法很长很长,其实主要就是三步,第一获取实现了BeanFactoryPostProcessor的类,第二根据优先级进行排序,第三根据排好的顺序循环执行。当然里面有Spring内置的BeanFactoryPostProcess,还有一些无需排序的BeanFactoryPostProcessor。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
发现是通过
PostProcessorRegistrationDelegate来执行。这就是代理模式啊,将接受请求的对象委托给另一个对象来处理,spring源码中大量的用到了委托模式,BeanDefition的解析委托给了BeanDefintionParseDelegate,属性值的解析委托给了BeanDefitionValueResolve。然后一下PostProcessorRegistrationDelegate里的
registerBeanPostProcessors方法。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List priorityOrderedPostProcessors = new ArrayList();
List internalPostProcessors = new ArrayList();
List orderedPostProcessorNames = new ArrayList();
List nonOrderedPostProcessorNames = new ArrayList();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
OrderComparator.sort(priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
OrderComparator.sort(orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List nonOrderedPostProcessors = new ArrayList();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
OrderComparator.sort(internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
也是很长很长,其实就是获取BeanPostProcessor然后注入给BeanFactory,具体的执行通过getBean()触发,getBean()的具体过程就不分析了,可以参考我之前的博文,这里主要看一下getBean()的初始化过程。代码如下
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
在看一下invokeInitMethod()方法
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction
在这俩个方法中除了之前我们测试中实现的初始化方法,还有一个执行Aware的方法,再说一下官方文档中说Spring提供了一系列的Aware接口使得bean可以从容器获取需要的资源。个人觉得不适合来控制Bean的初始化。
至此整个分析结束。