Spring拓展接口之BeanPostProcessor,我们来看看它的底层实现

  • 时间:
  • 浏览:14
  • 来源:大发时时彩_时时彩app平台_大发时时彩app平台

前言

  开心一刻

    小明:“妈,我被公司开除了”,妈:“啊,为那先 呀?”, 小明:“我骂董事长是笨蛋,公司召开高层会议都都可不可以 起诉我”,妈:“告你诽谤是吧?”,小明:“详细前会,.我都.我都.我都说要告我泄露公司机密”

BeanPostProcessor定义

  不管三七二十一,.我都.我都.我都先来看看它的定义,看看spring是何如描述BeanPostProcessor的

/*
 * Copyright 802-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

/**
 * 允许对新的bean示例进行自定义的修改,类似于于检查标志接口或进行代理封装
 *
 * spring上下文会在它的beng定义中自动检测BeanPostProcessor实例,并将它们应用于然后创建的每另一一一个多

bean实例
 *
 * implement {@link #postProcessAfterInitialization}.
 * 通常,通过实现BeanPostProcessor的postProcessBeforeInitialization法子

(配合标记接口,如@Autowired)来填充bean实例,
 * 通过BeanPostProcessor的postProcessAfterInitialization法子

进行bean实例的代理
 *
 */
public interface BeanPostProcessor {

    /**
     * 在bean实例的初始化法子

(类似于于InitializingBean的afterPropertiesSet或自定义的init-method)回调事先

,
     * spring会应用此法子

到bean实例上。一般用于bean实例的属性值的填充
     * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * <p>The default implementation returns the given {@code bean} as-is.
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one;
     * if {@code null}, no subsequent BeanPostProcessors will be invoked
     * @throws org.springframework.beans.BeansException in case of errors
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     */
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * 在bean实例的初始化法子

(类似于于InitializingBean的afterPropertiesSet或自定义的init-method)回调事先

,
     * spring会应用此法子

到bean实例上。
     * 在有FactoryBean时,此法子

会在FactoryBean实例与FactoryBean的目标对象创建时各调用一次
     * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
     * instance and the objects created by the FactoryBean (as of Spring 2.0). The
     * post-processor can decide whether to apply to either the FactoryBean or created
     * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
     * <p>This callback will also be invoked after a short-circuiting triggered by a
     * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
     * in contrast to all other BeanPostProcessor callbacks.
     * <p>The default implementation returns the given {@code bean} as-is.
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one;
     * if {@code null}, no subsequent BeanPostProcessors will be invoked
     * @throws org.springframework.beans.BeansException in case of errors
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     * @see org.springframework.beans.factory.FactoryBean
     */
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}
View Code

  简单点来理解,太满太满spring会自动从它的所有的bean定义中检测BeanPostProcessor类型的bean定义,因此实例化它们,再将它们应用于然后创建的每另一一一个多 bean实例,在bean实例的初始化法子 回调事先 调用BeanPostProcessor的postProcessBeforeInitialization的法子 (进行bean实例属性的填充),在bean实例的初始化法子 回调事先 调用BeanPostProcessor的postProcessAfterInitialization的法子 (可不都都可不可以 进行bean实例的代理封装)

应用示例

  .我都.我都.我都先来看个简单的示例,注意:肯能spring太满太满从spring容器中的bean定义中自动检测BeanPostProcessor类型的bean定义,太满太满.我都.我都.我都自定义的BeanPostProcessor要通过四种 法子 注册到spring容器

  MyBeanPostProcessor

  AnimalConfig

  Dog

  详细实例工程:spring-boot-BeanPostProcessor .我都.我都.我都来看看启动结果

  其他同学肯能会说了:“你是个逗比把,你举的因此 例子有那先 用? 实际上,根本就我太满 跳出BeanPostProcessor的原本 用法!”  有原本 的大疑问非常正常,示例中的BeanPostProcessor的另一一一个多 法子 :postProcessBeforeInitialization、postProcessAfterInitialization没做任何的处置,都太满太满直接返回bean,这我太满 多太满:脱了裤子放屁?

  .我都.我都.我都细看下,会发现postProcessBeforeInitialization、postProcessAfterInitialization中各多了一行打印(),随便说说示例太满太满验证下Spring对BeanPostProcessor的支持、BeanPostProcessor的另一一一个多 法子 的执行时机,与非 如BeanPostProcessor 的注释所说的那样,实际应用中肯定我太满 没有 用的。那大疑问来了:BeanPostProcessor能用来干那先 ? 回答因此 大疑问事先 ,.我都.我都.我都先来看看spring对BeanPostProcessor的底层支持

源码解析

  BeanPostProcessor的实例化与注册  

    很明显,.我都.我都.我都从spring的启动过程的refresh法子 开始英语 ,如下图

 

    此时spring容器中所有的BeanPostProcessor都进行了实例化,并注册到了beanFactory的beanPostProcessors属性中

    registerBeanPostProcessors

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.
    // 将所有BeanPostProcessor bean定义分三类:实现了PriorityOrdered、实现了Ordered,以及剩下的常规BeanPostProcessor
    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)) {
            // 实例化实现了PriorityOrdered接口的BeanPostProcessor
            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.
    // 注册实现了PriorityOrdered接口的BeanPostProcessor到beanFactory的beanPostProcessors属性中
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String ppName : orderedPostProcessorNames) {
        // 实例化实现了Ordered接口的BeanPostProcessor
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    // 注册实现了Ordered接口的BeanPostProcessor到beanFactory的beanPostProcessors属性中
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String ppName : nonOrderedPostProcessorNames) {
        // 实例化剩下的所有的常规的BeanPostProcessors
        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.
    // 注册所有常规的的BeanPostProcessor到beanFactory的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));
}
View Code

  BeanPostProcessor的生效时机

    前面.我都.我都.我都肯能知道,spring会应用BeanPostProcessor于然后创建的每另一一一个多 bean实例,具体spring是何如做到的了,.我都.我都.我都仔细来看看

    finishBeanFactoryInitialization法子 实例化所有剩余的、非延迟初始化的单例(默认状况下spring的bean详细前会非延迟初始化单例),具体如下

BeanPostProcessor应用场景

  随便说说若果.我都.我都.我都弄清楚了BeanPostProcessor的执行时机:在bean实例化事先 、初始化前后被执行,允许.我都.我都.我都对bean实例进行自定义的修改;若果.我都.我都.我都明白了因此 时机点,.我都.我都.我都就能分辨出BeanPostProcessor适用于那先 需求场景,那先 需求场景可不都都可不可以 用BeanPostProcessor来实现

  spring蕴含太满太满BeanPostProcessor的实现,.我都.我都.我都接触的比较多的自动装配:AutowiredAnnotationBeanPostProcessor也是BeanPostProcessor的实现之一,关于自动装配我会在下篇博文中与.我都.我都.我都一齐探索

总结

  spring中bean的生命周期如下图

    引用自:Spring实战系列(三)-BeanPostProcessor的妙用