spring BeanFactoryPostProcessor PathMatchingResourcePatternResolver

本文探讨了Spring框架中BeanFactoryPostProcessor与BeanPostProcessor两种扩展点的区别及使用场景,并详细介绍了通过ResourcePatternResolver和MetadataReaderFactory进行资源扫描的具体实现。

后处理:

BeanFactoryPostProcessor和BeanPostProcessor都是Spring初始化bean的扩展点。两个接口非常相似。

注意:BeanFactoryPostProcessor的回调比BeanPostProcessor要早


资源扫描:

ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
// 加载系统所有类资源
Resource[] resources = resourcePatternResolver.getResources("classpath*:/com/**/*"+type+".class");

for (Resource r : resources ) {
                    MetadataReader reader = metadataReaderFactory.getMetadataReader(r);
                    AnnotationMetadata annotationMD = reader.getAnnotationMetadata();
                 。。。。。。
 }


参考链接:

http://blog.youkuaiyun.com/xiao_jun_0820/article/details/7242379

http://blog.youkuaiyun.com/mn11201117/article/details/24986325

http://san-yun.iteye.com/blog/1426849

<think>我们正在讨论Spring框架中BeanFactoryPostProcessor的执行时机。根据之前的引用和Spring的生命周期,BeanFactoryPostProcessor是在Spring容器加载了Bean的定义之后,但在Bean实例化之前执行的。它主要用来修改Bean的定义(BeanDefinition),例如修改属性值或添加其他配置。引用[4]中提到:context:annotation-config和context:component-scan会扫描并注册实现了BeanFactoryPostProcessor和BeanPostProcessor的bean,这些bean会被当做处理器加入集合。而BeanFactoryPostProcessor的处理器链的加载过程在【springSpringIoC源码学习:invokeBeanFactoryPostProcessors详解中。另外,引用[2]中提到了一个关键方法:invokeBeanFactoryPostProcessors,这个方法就是用来执行所有BeanFactoryPostProcessor的。因此,我们可以总结如下:1.执行时机:在Spring容器初始化阶段,在BeanDefinition加载完成之后,但在任何Bean实例化(包括单例Bean的预实例化)之前。2.作用:可以修改Bean的定义(例如,修改属性值、改变Bean的作用域等),但不能修改Bean的实例,因为此时Bean还没有被创建。3.执行方法:通过PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法统一执行。具体步骤: -首先,Spring容器解析配置文件或注解,生成BeanDefinition并注册到BeanFactory。-然后,容器会查找所有实现了BeanFactoryPostProcessor接口的Bean,并按照优先级(如果有的话)执行它们。 -执行完毕后,才会继续后续的Bean实例化、属性注入、初始化等过程。注意:BeanFactoryPostProcessor和BeanPostProcessor的区别在于:- BeanFactoryPostProcessor操作的是Bean的定义(BeanDefinition),在Bean实例化之前。- BeanPostProcessor操作的是Bean的实例,在Bean初始化前后。引用[5]中也提到:BeanFactoryPostProcessor是在Bean实例化之前执行的。因此,我们可以用以下流程图表示:```mermaidgraph LRA[加载Bean定义]--> B[执行BeanFactoryPostProcessor]B -->C[实例化Bean]C--> D[属性注入]D--> E[初始化回调等] ```示例代码:我们可以实现一个BeanFactoryPostProcessor,来修改某个Bean的定义。```java@Componentpublic classMyBeanFactoryPostProcessor implementsBeanFactoryPostProcessor{@Overridepublic voidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)throws BeansException {BeanDefinition beanDefinition =beanFactory.getBeanDefinition("myBean");//修改属性值beanDefinition.getPropertyValues().add("name", "modifiedName");} }```在这个例子中,我们在Bean实例化之前修改了名为"myBean"的Bean的属性"name"的值。总结:BeanFactoryPostProcessor的执行时机是在BeanDefinition加载完成之后,Bean实例化之前。它是Spring容器初始化阶段的一个重要扩展点,允许我们修改Bean的配置元数据。相关问题: 1. BeanFactoryPostProcessor和BeanPostProcessor的主要区别是什么? 2.如何控制多个BeanFactoryPostProcessor的执行顺序? 3. BeanFactoryPostProcessor能否修改Bean的作用域?如何修改?</think>### Spring BeanFactoryPostProcessor 的执行时机 `BeanFactoryPostProcessor` 是 Spring 容器生命周期中**最早执行**的扩展点之一,其核心执行时机如下: 1. **触发阶段** 在 Spring 容器完成以下操作后立即执行: - 加载所有配置元数据(XML/注解/Java Config) - 解析并注册所有 Bean 的定义(`BeanDefinition`) - **但尚未开始实例化任何 Bean** 2. **执行位置** 位于容器初始化流程的 `refresh()` 方法中,具体在 `invokeBeanFactoryPostProcessors()` 阶段触发: ```java // AbstractApplicationContext.refresh() invokeBeanFactoryPostProcessors(beanFactory); // 执行点 ``` 3. **关键特征** - 🚫 **不涉及 Bean 实例**:仅操作 `BeanDefinition`(元数据) - ✅ **修改 Bean 配置**:可修改属性值、作用域、初始化方法等 - ⚙️ **工厂级操作**:影响后续所有 Bean 的创建行为 --- ### 生命周期中的定位 ```mermaid graph LR A[加载配置] --> B[注册BeanDefinition] B --> C[执行BeanFactoryPostProcessor] C --> D[实例化Bean] D --> E[执行BeanPostProcessor] ``` > **关键节点对比**: > | 处理器类型 | 操作对象 | 执行时机 | > |---------------------------|-------------------|------------------------------| > | `BeanFactoryPostProcessor`| `BeanDefinition` | Bean 实例化**前** | [^4] > | `BeanPostProcessor` | Bean **实例** | Bean 初始化**前后** | --- ### 源码执行流程 1. 容器通过 `PostProcessorRegistrationDelegate` 统一调度(门面模式)[^2]: ```java // AbstractApplicationContext protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors( beanFactory, getBeanFactoryPostProcessors() ); } ``` 2. 处理器按优先级顺序执行: - 先执行 `BeanDefinitionRegistryPostProcessor`(子接口) - 再执行标准 `BeanFactoryPostProcessor` --- ### 典型应用场景 ```java @Component public class CustomBeanFactoryPP implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) { BeanDefinition bd = factory.getBeanDefinition("myService"); // 修改Bean作用域 bd.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE); // 添加初始化方法 bd.setInitMethodName("customInit"); } } ``` 此处理器在 Bean 实例化前修改了 `myService` 的元数据[^4]。 --- ### 与其他扩展点的关系 - **在 `Aware` 接口之前执行**:所有 `Aware` 方法(如 `BeanNameAware`)都在 Bean 实例化阶段触发,远晚于 `BeanFactoryPostProcessor`[^5] - **先于 `BeanPostProcessor`**:工厂级处理器执行完成后,才会创建 Bean 并触发实例级处理器[^1] > ⚠️ 注意:`BeanFactoryPostProcessor` **不适用于 prototype bean** 的销毁阶段,因为 Spring 不管理其完整生命周期[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值