来源:江南一点雨 今天来和各位小伙伴详细分析一下 BeanPostProcessor。时介今天这篇是时介原理分析,基本用法松哥之前已经讲过了,时介有视频也有文章,时介对视频感兴趣的时介小伙伴戳这里:Spring源码应该怎么学?。 不同于前面和大家分享的时介 BeanFactoryPostProcessor,BeanPostProcessor 从名字上就能看出来,时介这是时介一个 Bean 的后置处理器,也就是时介说,BeanPostProcessor 其实主要是时介对已经创建出来的 Bean 做一些后置处理,而 BeanFactoryPostProcessor 主要是时介针对 BeanDefinition 做后置处理(此时 Bean 对象还没创建出来)。 但是时介,BeanPostProcessor 家族里边也有例外,时介即 MergedBeanDefinitionPostProcessor,时介这是时介一个 BeanPostProcessor,但是却可以处理 BeanDefinition。 这一切都是咋回事呢?我们今天就来分析分析。 首先我们先来看一下 BeanPostProcessor 接口的定义: { { bean; } { bean; } } 这里就是两个方法,理解这两个方法有一个大的站群服务器前提,就是此时 Spring 容器已经通过 Java 反射创建出来 Bean 对象了,只不过在初始化这个 Bean 对象的时候,又提供了一些配置接口: BeanPostProcessor 的应用非常广泛,在整个 Spring 体系中,也扮演了非常重要的角色,如 @Bean 注解的解析、AOP 动态代理的生成等等许多我们日常使用的功能,都是通过 BeanPostProcessor 来实现的。 MergedBeanDefinitionPostProcessor 算是整个 BeanPostProcessor 家族中比较另类的一个接口了,源码下载它虽然是 BeanPostProcessor,但是却可以处理 BeanDefinition。MergedBeanDefinitionPostProcessor 介入的时机就是 Bean 创建成功之后,Bean 中各个属性填充之前。 MergedBeanDefinitionPostProcessor 用于在 Bean 定义合并之后对合并后的 Bean 进行后置处理。它的作用是允许开发者在 Bean 定义合并完成后,对合并后的 Bean 进行自定义的修改或扩展操作。通常情况下,这个接口用于处理带有注解的 Bean 定义,例如 @Autowired 或 @Value 等注解的处理。通过实现 MergedBeanDefinitionPostProcessor 接口,开发者可以在 Bean 定义合并后,对这些注解进行解析和处理,以实现自定义的逻辑。 来看下 MergedBeanDefinitionPostProcessor 接口: { ; { } } 这里就两个方法,一个是处理合并后的 BeanDefinition,还有一个是重置 Bean 的。亿华云计算 接下来我们来看 BeanPostProcessor 的处理流程,首先第一步就是在容器启动的时候,收集到用户注册在系统中的 BeanPostProcessor,无论是 Java 配置还是 XML 配置,在 refresh 方法中都会调用到 registerBeanPostProcessors,这个方法就是用来收集 BeanPostProcessor 的。 { ); } ( { ; + postProcessorNames.length; BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); ArrayList<>(); ArrayList<>(); ArrayList<>(); ArrayList<>(); (String ppName : postProcessorNames) { { ; priorityOrderedPostProcessors.add(pp); MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } { orderedPostProcessorNames.add(ppName); } { nonOrderedPostProcessorNames.add(ppName); } } sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); ArrayList<>(orderedPostProcessorNames.size()); (String ppName : orderedPostProcessorNames) { ; orderedPostProcessors.add(pp); MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); ArrayList<>(nonOrderedPostProcessorNames.size()); (String ppName : nonOrderedPostProcessorNames) { ; nonOrderedPostProcessors.add(pp); MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); ApplicationListenerDetector(applicationContext)); } 这里的代码我就不逐行解释了,我来说一下整体的处理思路。 这里用来存储 BeanPostProcessor 的集合一共有四个,分别是: 将收集并且排序好的 BeanPostProcessor,调用 registerBeanPostProcessors 方法进行注册: ( { AbstractBeanFactory abstractBeanFactory) { abstractBeanFactory.addBeanPostProcessors(postProcessors); } { (BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); } } } 这里最终就是把收集到的 BeanPostProcessor 添加到容器的 beanPostProcessors 变量中。 现在,容器中已经有了 BeanPostProcessor 了,接下来看什么时候执行。 BeanPostProcessor 的执行分为两种情况,一种是执行 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor,还有一种是执行普通的 BeanPostProcessor,我们分别来看。 在创建 Bean 的关键方法 AbstractAutowireCapableBeanFactory#doCreateBean 中,有这样几个关键步骤: { ; (mbd.isSingleton()) { .factoryBeanInstanceCache.remove(beanName); } ) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class beanType = instanceWrapper.getWrappedClass(); { mbd.resolvedTargetType = beanType; } (mbd.postProcessingLock) { (!mbd.postProcessed) { { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } (Throwable ex) { BeanCreationException(mbd.getResourceDescription(), beanName, , ex); } mbd.markAsPostProcessed(); } } { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } exposedObject; } 大家看到,在初始化 Bean 实例之后,有一个 applyMergedBeanDefinitionPostProcessors 方法,这个方法就是用来触发 MergedBeanDefinitionPostProcessor 执行的。 populateBean 方法是给 Bean 的各个属性填充值的,填充完成之后,调用 initializeBean 方法进行剩余的初始化工作,在 initializeBean 方法中,调用了其余的 BeanPostProcessor。 { (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) { processor.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } { invokeAwareMethods(beanName, bean); Object wrappedBean = bean; || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } { invokeInitMethods(beanName, wrappedBean, mbd); } (Throwable ex) { BeanCreationException( ), beanName, ex.getMessage(), ex); } || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } wrappedBean; } 大家看这个顺序,先是调 applyBeanPostProcessorsBeforeInitialization,这个里边最终就触发到了 BeanPostProcessor#postProcessBeforeInitialization 方法;然后调用 invokeInitMethods,afterPropertiesSet 和自定义的 init-method 都在这里被触发;最后调用 applyBeanPostProcessorsAfterInitialization,这个里边最终就触发到 BeanPostProcessor#postProcessAfterInitialization 方法。 好啦,这就是和小伙伴们梳理的 BeanPostProcessor 原理了,感兴趣的小伙伴可以自己 DEBUG 跑一遍哦~1. BeanPostProcessor
2. MergedBeanDefinitionPostProcessor
3. 收集 BeanPostProcessor
4. 触发 BeanPostProcessor
4.1 触发 MergedBeanDefinitionPostProcessor
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) 4.2 触发其他 BeanPostProcessor
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)