美文网首页
spring4 IOC的Bean后置处理器

spring4 IOC的Bean后置处理器

作者: sunpy | 来源:发表于2020-09-15 16:16 被阅读0次

    介绍

    spring提供了初始化方法的扩展入口,给用户权限来更改或者扩展spring。bean后置处理器注册之后,然后spring容器通过回调方式调用方法。(实现BeanPostProcessor接口,然后注册到spring容器,将会被容器执行回调方法postProcessBeforeInitialization、postProcessAfterInitialization)



    postProcessBeforeInitialization方法:bean初始化之前回调的方法。
    postProcessAfterInitialization方法:bean初始化之后回调的方法。

    示例

    public class User {
        
        public User() {
            System.out.println("构造 User");
        }
    }
    public class PrintBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessBeforeInitialization() " + beanName);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessAfterInitialization() " + beanName);
            return bean;
        }
    }
    
    <beans:bean id="printBeanPostProcessor" class="cn.spy.spring.source.code.PrintBeanPostProcessor"></beans:bean>
    <beans:bean id="user" class="cn.spy.spring.source.code.User"></beans:bean>
    
    ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
    ac.getBean(User.class);
    

    BeanPostProcessor后置处理器注册

    // 注册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<BeanPostProcessor>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        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接口的BeanPostProcessors
        OrderComparator.sort(priorityOrderedPostProcessors);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
        // 其次,注册实现了Ordered接口的BeanPostProcessors
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        OrderComparator.sort(orderedPostProcessors);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    
        // 现在,注册规则的BeanPostProcessors
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    
        // 最后,注册内部实现的BeanPostProcessors
        OrderComparator.sort(internalPostProcessors);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);
    
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }
    

    循环遍历BeanPostProcessor集合,将BeanPostProcessor注册到BeanFactory。

    private static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    
        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }
    

    BeanPostProcessor后置处理器执行

    分析入口:bean实例化,属性填充

    // 创建指定的bean
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            // 对于单例Bean,先从容器中缓存中获取同名Bean
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // 创建实例对象
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        // 获取实例化对象的类型
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    
        // 调用PostProcessor后置处理器
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                mbd.postProcessed = true;
            }
        }
    
        // 向容器中缓存单例Bean对象,以防循环引用  
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            // 为了防止循环引用,尽早持有对象的引用  
            addSingletonFactory(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }
    
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            // 将Bean实例对象封装,并且对bean进行填充,将各个属性值注入。
            // 如果存在依赖其他bean的属性,则递归初始依赖bean
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                // 初始化bean对象,比如init-method
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }
    
        if (earlySingletonExposure) {
            // 获取指定名称的已注册的单例Bean对象
            Object earlySingletonReference = getSingleton(beanName, false);
            // 循环依赖的情况下,earlySingletonReference不为空
            if (earlySingletonReference != null) {
                // exposedObject没有在初始化方法中被改变,也就是没有被增强
                if (exposedObject == bean) {
                    // 当前实例化的Bean初始化完成
                    exposedObject = earlySingletonReference;
                }
                // 当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                    // 获取当前Bean所依赖的其他Bean 
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }
    
        // 注册完成依赖注入的Bean
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
    
        return exposedObject;
    }
    

    说明:
    ① 对于单例bean,先从factoryBeanInstanceCache缓存中移除beanName,返回BeanWrapper。
    ② createBeanInstance方法:实例化bean,BeanDefinition转换BeanWrapper。
    ③ 允许后处理修改合并BeanDefinition(譬如:autowired注解预解析)。
    ④ 循环依赖的处理。
    ⑤ 属性填充,将所有的属性填充到bean实例(populateBean方法)
    ⑥ 执行init-method方法和bean后置处理器(initializeBean方法)
    ⑦ registerDisposableBeanIfNecessary方法:注册DisposableBean,便于执行配置的destory-method。


    在createBeanInstance方法实例化bean、populateBean方法填充属性。然后才开始执行initializeBean方法进行init-method和bean后置处理器回调。至于bean后置处理器跟随前面bean的实例化和属性填充的。所以bean的实例化的时机分为两个:第一个是getBean方法的调用。第二个是finishBeanFactoryInitialization方法的调用,非懒加载的预实例化。所以bean后置处理器的执行在非懒加载的预实例化的时候执行。


    initializeBean方法初始化给定的bean实例,执行设置的init-method方法、执行BeanPostProcessor回调方法

    // 初始化给定的bean实例
    // 执行设置的init-method方法、执行BeanPostProcessor回调方法
    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
    
        // 在init-method方法之前执行postProcessBeforeInitialization方法
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    
        // 反射方式执行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);
        }
    
        // 在init-method方法之后执行postProcessAfterInitialization方法
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }
    

    initializeBean方法说明:
    ① 执行BeanPostProcessor的前置方法postProcessBeforeInitialization(applyBeanPostProcessorsBeforeInitialization)。
    ② 执行init-method的方法。
    ③ 执行BeanPostProcessor的前置方法postProcessAfterInitialization
    (applyBeanPostProcessorsAfterInitialization)。

    // 遍历BeanPostProcessor
    // 执行postProcessBeforeInitialization方法
    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
    
        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
            if (result == null) {
                return result;
            }
        }
        return result;
    }
    
    // 遍历BeanPostProcessor
    // 执行postProcessAfterInitialization方法
    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {
    
        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
            if (result == null) {
                return result;
            }
        }
        return result;
    }
    

    所以示例的打印顺序很清晰了,先实例化bean,执行了构造器方法,然后在执行BeanPostProcessor。

    相关文章

      网友评论

          本文标题:spring4 IOC的Bean后置处理器

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