spring的BeanPostProcessor详解

参考文档:https://www.jianshu.com/p/6d7f01bc9def

首先当然是先亮源码了。接口也能实现,可能是java语法支持的吧。源码如下:

public interface BeanPostProcessor {
    //初始化前,用户自定义操作。接口也能实现
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
   //初始化后,用户自定义操作
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}

一、当然是看这个类在哪里使用了。使用方式在如下,在doCreateBean方法里面,初始化Bean的时候用。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

initializeBean方法就不说了,大家都知道它来自哪里。现在我们解释的是,它的作用。初始化Bean,那怎么初始化呢?看源码,分三步走,很清晰。

  1. applyBeanPostProcessorsBeforeInitialization方法
  2. 然后执行init-method方法,invokeinitMethods()方法
  3. 最后执行applyBeanPostProcessorsAfterInitialization方法

二、BeanPostProcessor的使用方式了解了,那么这个类怎么用呢?我们该如何实现呢?

参考文章地址

@Service
public class MyDemoBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(
                "bean=" + bean.getClass().getName() + " postProcessBeforeInitialization....");
        return bean;
    }

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

BeanPostProcessor的实现类必须也是一个bean,并且对所有bean的初始化都生效。如何做到对指定的bean生效呢?好像能做的,就是在这个实现类里面,对类名进行指定。在这个实现类里面,可以做自己的业务。

  • 比如最常见的aspectJ的aop功能,就是通过AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor的postProcessBeforeInstantiation方法,代理了原始类,生成了新类。
  • 比如极特殊的InstantiationAwareBeanPostProcessor类,spring对他特殊处理。具体下面会介绍。
  • 当然还有很多Spring自己原生实现的BeanPostProcessor类,就不一一介绍了。遇到了在解释

三、特殊类InstantiationAwareBeanPostProcessor(也是接口)源码解析

参考文章
为啥说这个类特殊呢?难道它和其他BeanPostProcessor的实现类,有啥不同吗?
答案就是它确实是和其他实现类不同,不同的地方是,Spring专门在populateBean方法中,提前调用了BeanPostProcessor 的postProcessBeforeInstantiation方法或者postProcessAfterInitialization方法,用来达到特殊化初始化Bean。

该接口在BeanPostProcessor的基础上,新增了四个方法。postProcessBeforeInstantiation ,postProcessAfterInstantiation postProcessProperties和postProcessPropertyValues。可以发现这两个方法是初始化bean的属性用的。如果bean的属性有其他bean,那么就达到了递归创建bean的目的。

吐槽下:两个类的其中有两对方法名太像了。
postProcessBeforeInstantiation-实例化前处理函数
postProcessBeforeInitialization-初始化前处理函数
postProcessAfterInstantiation-实例化后处理函数
postProcessAfterInitialization-初始化后处理函数

  • 比如接口InstantiationAwareBeanPostProcessor的一个实现类AutowiredAnnotationBeanPostProcessor,就是@Autowired,@Resouce注解的PostProcessor实现了。到现在终于清晰了创建Bean的过程
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }

    @Nullable
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {
        return null;
    }

    @Deprecated
    @Nullable
    default PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    }

}

四、BeanPostProcessor是怎么注册的呢?

refresh方法中的

    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);

BeanPostProcessor的bean是最开始初始化的。

/**
     * Instantiate and register all BeanPostProcessor beans,
     * respecting explicit order if given.
     * <p>Must be called before any instantiation of application beans.
     */
//英文注释上,清楚的写到:初始化并注册所有的BeanPostProcessor实现类。
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

实现源码:

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<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> 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.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // Next, register the BeanPostProcessors that implement Ordered.
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // Now, register all regular BeanPostProcessors.
        List<BeanPostProcessor> 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.
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }
  • 优先级最高的:priorityOrderedPostProcessors
  • 优先级中间的:orderedPostProcessorNames
  • 优先级最低的:nonOrderedPostProcessorNames
    可以看到,beanPostProcessor的创建,按照优先程度,分为三类。每一类都会按照sortPostProcessors方法排序。然后按照顺序registerBeanPostProcessors到beanFactory中。可想而知,beanPostProcessors队列就是按照优先级高低排好序的,bean在实例化或者初始化的时候,使用也是按照这个顺序依次执行的。

总结:Spring的源码浩瀚复杂,我也只能窥其一斑,继续学习。有错误的地方,欢迎指正。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 本来是准备看一看Spring源码的。然后在知乎上看到来一个帖子,说有一群**自己连Spring官方文档都没有完全读...
    此鱼不得水阅读 11,832评论 4 21
  • Spring容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相...
    Theriseof阅读 7,841评论 1 24
  • 一、Spring IOC其实很简单  有部分Java开发者对IOC(Inversion Of Control)和D...
    Chandler_珏瑜阅读 9,964评论 0 41
  • 像是一个被放在一个又一个时间的格子上的装饰物,独享着秘密的美好
    此致不渝阅读 1,153评论 0 0
  • 一般的头文件的布局: #ifndef _NAME_ #define_NAME_ \\防卫式声明 #include<...
    0ffa31abb8f8阅读 1,648评论 0 0

友情链接更多精彩内容