美文网首页
BeanPostProcessor 的用法

BeanPostProcessor 的用法

作者: RojerAlone | 来源:发表于2019-10-11 20:33 被阅读0次

    BeanPostProcessor 的用法

    BeanPostProcessor 是 Spring 对外提供的一个扩展,用于在 bean 初始化阶段对 bean 做一些特殊的处理。

    BeanPostProcessor 的定义及作用

    public interface BeanPostProcessor {
    
        Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    
        Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    
    }
    

    BeanPostProcessor 中定义两个方法,postProcessBeforeInitializationpostProcessAfterInitialization,调用时机分别是在 bean 被初始化之后,继承自 InitializingBeanafterPropertiesSet 方法或者 xml 文件中定义的 init-method 方法被调用之前,而 postProcessAfterInitialization 是在这种 callback 方法被调用之后执行。

    如下图所示(简书上没法解析有道云的流程图语法):

    graph TD
    A[Bean 实例化/ 设置属性 / 回调 Aware 等操作] --> B[调用 postProcessBeforeInitialization]
    B --> C[调用 afterPropertiesSet / init-method 等回调方法]
    C --> D[调用 postProcessAfterInitialization 方法]
    D --> E[其他操作...]
    

    BeanPostProcessor 的源码分析

    bean 的初始化是在 refresh 方法中进行的,首先将 BeanPostProcessor 注册到 BeanFactory 中,在执行 initializeBean 的时候再调用,注册是在 registerBeanPostProcessors(beanFactory) 进行的:

    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
    

    继续查看 registerBeanPostProcessors 方法:

        public static void registerBeanPostProcessors(
                ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    
            // 获取所有的 BeanPostProcessor bean 名字
            String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
            // ...
    
            // 根据不同的优先级,内部 processor 以及 Order 排序,再处理
            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);
                }
            }
    
            // 先注册实现了 PriorityOrdered 接口的
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
            registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
            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);
                }
            }
            // 再注册实现了 Ordered 接口的
            sortPostProcessors(orderedPostProcessors, beanFactory);
            registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    
            // 然后注册没有指定优先级的
            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);
    
            // 最后注册内部的
            sortPostProcessors(internalPostProcessors, beanFactory);
            registerBeanPostProcessors(beanFactory, internalPostProcessors);
    
            // 最后添加一个 Spring 自带的
            beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
        }
    

    在 bean 初始化时候调用 postProcessBeforeInitializationpostProcessAfterInitialization

        protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
            // 处理 Aware
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }, getAccessControlContext());
            }
            else {
                invokeAwareMethods(beanName, bean);
            }
            // 先调用 postProcessBeforeInitialization
            Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
            // 再调用 afterPropertiesSet / init-method 等回调方法
            try {
                invokeInitMethods(beanName, wrappedBean, mbd);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(
                        (mbd != null ? mbd.getResourceDescription() : null),
                        beanName, "Invocation of init method failed", ex);
            }
            // 最后调用 postProcessAfterInitialization
            if (mbd == null || !mbd.isSynthetic()) {
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
    
            return wrappedBean;
        }
    

    BeanPostProcessor 的应用场景

    Spring 内部使用 BeanPostProcessor 来进行 bean 的增强,比如 AOP,Dubbo 中也使用 BeanPostProcessor 来实现 @Reference 注解的对象注入。

    在我做过的项目中,使用 BeanPostProcessor 进行了和 Dubbo 类似的操作,对自定义注解进行了注入,比如定义了一个 @Person 注解,在 postProcessBeforeInitialization 中读取传入的 bean 是不是符合要求的,如果是符合要求的,注入一个自定义的对象到 bean 中标注了 @Person 注解的属性中。

    相关文章

      网友评论

          本文标题:BeanPostProcessor 的用法

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