Spring源码分析:BeanPostProcessor原理

栏目: Java · 发布时间: 5年前

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;
}
  1. 首先获取到所有的后置处理器getBeanPostProcessors()
  2. 在for循环中依次调用后置处理器的方法beanProcessor.postProcessBeforeInitialization(result, beanName);
  3. 进入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);
        }
    }
}
  1. 来到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便身不由己了。


以上所述就是小编给大家介绍的《Spring源码分析:BeanPostProcessor原理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

光线跟踪算法技术

光线跟踪算法技术

萨芬 / 刘天慧 / 清华大学出版社 / 2011-3 / 98.00元

《光线跟踪算法技术》详细阐述了与光线跟踪问题相关的高效解决方案及相应的数据结构和算法,主要包括采样技术、投影视图、视见系统、景深、非线性投影、立体视觉、光照与材质、镜面反射、光泽反射、全局光照、透明度、阴影、环境遮挡、区域光照、光线与对象间的相交计算、对象变换、栅格技术以及纹理映射技术等内容。此外,《光线跟踪算法技术》还提供了相应的算法、代码以及伪代码,以帮助读者进一步理解计算方案的实现过程。 ......一起来看看 《光线跟踪算法技术》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具