乐趣区

Spring源码分析:BeanPostProcessor原理

BeanPostProcessor 即,Bean 的后置处理器,它的作用就是在 Bean 的初始化方法前跟后进行拦截处理。我们都知道,要想在 Bean 的初始化方法前后进行工作,那必须在 Bean 实例创建完成之后,init 方法执行之前,后置处理器就已经在容器中了,所以我们来到向容器中添加后置处理器的类 AbstractApplicationContext,其中 refresh()中的 registerBeanPostProcessors(beanFactory)就是首先向容器中注册我们所需要的所有后置处理器。如何注册后置处理器我们暂不作分析,着重说一下,后置处理器是如何工作的。
代码实现
实现类:
@Component
public class BeanPostProcessorImpl implements BeanPostProcessor {

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 返回一个传过来的对象
// 在初始化方法调用之前进行后置处理工作
// 什么时候调用呢?在 init-method 方法之前就调用了
System.out.println(“postProcessBeforeInitialization======” + beanName + “======” + bean);
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(“postProcessAfterInitialization======” + beanName + “======” + bean);
return bean;
}

}
配置类:
@Configuration
@ComponentScan(“com.nmys.story.springCore.springioc.beanpostprocessor_”)
public class Config01 {

@Bean(initMethod = “init”,destroyMethod = “destroy”)
public Train train(){
return new Train();
}

}
实体类:
/**
* @author 70KG
* @Title: Train
* @Description:
* @date 2018/7/23 下午 11:31
* @From www.nmyswls.com
*/
public class Train {

private String name = “ 火车 ”;

private Integer length = 150;

public Train() {
System.out.println(“Train 构造方法执行。。。。。。”);
}

public void init() {
System.out.println(“Train 的 init 方法执行。。。。。。”);
}

public void destroy() {
System.out.println(“Train 的 destroy 方法执行。。。。。。”);
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getLength() {
return length;
}

public void setLength(Integer length) {
this.length = length;
}
}
测试类:
public class Test01 {
@Test
public void test() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config01.class);
ac.close();
}
}
打印结果:
Train 构造方法执行。。。。。。
postProcessBeforeInitialization======train======com.nmys.story.springCore.springioc.beanpostprocessor_.Train@5aa9e4eb
Train 的 init 方法执行。。。。。。
postProcessAfterInitialization======train======com.nmys.story.springCore.springioc.beanpostprocessor_.Train@5aa9e4eb
Train 的 destroy 方法执行。。。。。。
结果分析:
首先 Train 构造方法执行创建对象,然后执行了后置处理器的 Before 方法,然后才调用 init 方法,init 方法执行完成,再执行后置处理器的 After 方法,最后容器关闭执行销毁方法。
BeanPostProcessor 原理分析
AnnotationConfigApplicationContext 构造方法中的 refresh();
-> AbstractApplicationContext550 行 finishBeanFactoryInitialization(beanFactory); 完成剩余 Bean 的初始化工作
-> AbstractApplicationContext869 行 beanFactory.preInstantiateSingletons();
-> DefaultListableBeanFactory760 行 getBean(beanName);
-> AbstractBeanFactory317 行 createBean(beanName, mbd, args);
-> AbstractAutowireCapableBeanFactory503 行 doCreateBean(beanName, mbdToUse, args);
-> AbstractAutowireCapableBeanFactory580 行 populateBean(beanName, mbd, instanceWrapper); 在执行初始化之前,首先给实例赋值
-> AbstractAutowireCapableBeanFactory581 行 exposedObject = initializeBean(beanName, exposedObject, mbd); 准备执行初始化方法
-> AbstractAutowireCapableBeanFactory1700 行 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
-> AbstractAutowireCapableBeanFactory1704 行 invokeInitMethods(beanName, wrappedBean, mbd);
-> AbstractAutowireCapableBeanFactory1712 行 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
分析 AbstractAutowireCapableBeanFactory 的 applyBeanPostProcessorsBeforeInitialization 方法:
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

首先获取到所有的后置处理器 getBeanPostProcessors()
在 for 循环中依次调用后置处理器的方法 beanProcessor.postProcessBeforeInitialization(result, beanName);
进入 postProcessBeforeInitialization 方法(这个方法必须在 debug 过程中才可以进入)

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((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
<!–more–>
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);
}
}
}
来到 ApplicationContextAwareProcessor 类的 79 行,首先判断此 bean 是不是各种的 Aware,如果是它列举的那几个 Aware 就获取 Bean 工厂的权限,可以向容器中导入相关的上下文环境,目的是为了 Bean 实例能够获取到相关的上下文,如果不是 (显然它也不是) 它列举的几个 Aware,那就调用 invokeAwareInterfaces(bean),向容器中添加相关接口的上下文环境,显然我们自己的实现类也不属于 Aware 接口,所以这个处理结果直接将 Bean 返回,不做任何处理。ok,这样初始化之前的方法就分析完了,初始化之后的方法跟前面的流程一模一样。
总结
BeanPostProcessor 就是在 Bean 实例创建之后,在进行 populateBean 赋值之后,init 初始化方法之前进行一次调用,init 方法之后进行一次调用,这样一来,整个 Bean 的生命周期,全部掌控在了 Spring 之下,包括 Bean 实例创建 new Instance(),赋值前后 populateBean(),初始化前后 init(),销毁前后 destroy()。从此 Bean 便身不由己了。

退出移动版