Spring拓展接口之BeanPostProcessor,我们来看看它的底层实现
- 时间:
- 浏览:3
前言
开心一刻
小明:“妈,我被公司开除了”,妈:“啊,为那些呀?”, 小明:“我骂董事长是笨蛋,公司召开高层会议都要起诉我”,妈:“告你诽谤是吧?”,小明:“都是,我说要告我泄露公司机密”
BeanPostProcessor定义
不管三七二十一,亲戚朋友儿先来看看它的定义,看看spring是怎样描述BeanPostProcessor的
/* * Copyright 1502-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; } }
简单点来理解,就说 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中各多了一行打印(
源码解析
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)); }
BeanPostProcessor的生效时机
前面亲戚朋友儿曾经 知道,spring会应用BeanPostProcessor于让你创建的每曾经bean实例,具体spring是怎样做到的了,亲戚朋友儿仔细来看看
finishBeanFactoryInitialization办法实例化所有剩余的、非延迟初始化的单例(默认状况下spring的bean都是非延迟初始化单例),具体如下
BeanPostProcessor应用场景
我我嘴笨 我希望亲戚朋友儿弄清楚了BeanPostProcessor的执行时机:在bean实例化曾经 、初始化前后被执行,允许亲戚朋友儿对bean实例进行自定义的修改;我希望亲戚朋友儿明白了这名时机点,亲戚朋友儿就能分辨出BeanPostProcessor适用于那些需求场景,那些需求场景都要用BeanPostProcessor来实现
spring富含全都BeanPostProcessor的实现,亲戚朋友儿接触的比较多的自动装配:AutowiredAnnotationBeanPostProcessor也是BeanPostProcessor的实现之一,关于自动装配我会在下篇博文中与亲戚朋友儿一块儿探索
总结
spring中bean的生命周期如下图
引用自:Spring实战系列(三)-BeanPostProcessor的妙用