美文网首页
spring的BeanPostProcessor详解

spring的BeanPostProcessor详解

作者: 7d972d5e05e8 | 来源:发表于2019-10-04 08:14 被阅读0次

    参考文档: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的源码浩瀚复杂,我也只能窥其一斑,继续学习。有错误的地方,欢迎指正。

    相关文章

      网友评论

          本文标题:spring的BeanPostProcessor详解

          本文链接:https://www.haomeiwen.com/subject/xxdeuctx.html