Spring中BeanFactoryPostProcessor注解原理如何解析?

2026-05-25 21:111阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1304个文字,预计阅读时间需要6分钟。

Spring中BeanFactoryPostProcessor注解原理如何解析?

目录概述BeanFactoryPostProcessor的调用时机案例实践源码分析小结概述描述BeanFactoryPostProcessor的调用时机、案例实践、源码分析等。

案例实践以一个简单的Spring Boot项目为例,展示如何使用BeanFactoryPostProcessor。

源码分析分析BeanFactoryPostProcessor在Spring框架中的源码实现。

小结总结BeanFactoryPostProcessor的使用方法和注意事项。

概述Spring框架中的BeanFactoryPostProcessor是一个在Bean初始化之前被调用的接口,它允许我们在Bean定义之前修改BeanFactory。本节将介绍BeanFactoryPostProcessor的调用时机、案例分析、源码解析等。

BeanFactoryPostProcessor的调用时机在Spring容器初始化过程中,BeanFactoryPostProcessor会在BeanDefinitionRegistryPostProcessor接口的实现类(如PostProcessorRegistrationPostProcessor)之后被调用,但在Bean实例化之前。

案例实践以下是一个使用BeanFactoryPostProcessor的简单示例:

javaimport org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.stereotype.Component;

@Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 在这里修改BeanFactory,例如添加一个新的属性 beanFactory.getPropertyValues().add(newProperty, newValue); }}

源码分析在Spring框架中,BeanFactoryPostProcessor的调用是由AbstractApplicationContext类的refresh()方法控制的。以下是相关的源码片段:

javapublic void refresh() throws BeansException, IllegalStateException { // ... invokeBeanFactoryPostProcessors(beanFactory); // ...}

private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // ... List beanFactoryPostProcessors=beanFactory.getBeanFactoryPostProcessors(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } // ...}

小结通过使用BeanFactoryPostProcessor,我们可以修改BeanFactory,从而影响Spring容器的行为。了解其调用时机和实现原理对于深入理解Spring框架的运作机制非常重要。希望这些内容能够帮助大家更好地学习Spring。

目录
  • 概述
  • BeanFactoryPostProcessor的调用时机
  • 案例实践
  • 源码分析
  • 小结

概述

我们现在来学习一下Spring里面的一些扩展原理,希望大家通过这些原理的学习,对Spring里面的运行机制,包括其内部的工作原理,能有一个非常深刻的认识,为以后学习Spring里面的其他框架会有较大的帮助。

BeanFactoryPostProcessor的调用时机

BeanFactoryPostProcessor其实就是BeanFactory(创建bean的工厂)的后置处理器。

看到BeanFactoryPostProcessor会联想到BeanPostProcessor,之前说过它是bean的后置处理器,并且是在bean创建对象初始化前后进行拦截工作的。

看完接口上的描述后,我们可以指定BeanFactoryPostProcessor的调用时机。意思是在IOC容器的BeanFactory标准初始化完成之后,修改IOC容器里面的BeanFactory。

什么是标准初始化么?后面描述是所有的bean定义已经被加载了,但是还没有bean被初始化。

总结:BeanFactoryPostProcessor的调用时机是在BeanFactory标准化之后,我们可以定制、修改BeanFactory里面的一些内容,此时,所有的bean定义已经被加载到BeanFactory中了,但是bean的实例还没创建。

案例实践

首先编写一个类实现BeanFactoryPostProcessor接口。

package com.meimeixia.ext; import java.util.Arrays; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; @Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory..."); // 这个时候我们所有的bean还没被创建 // 但是我们可以看一下通过Spring给我们传过来的这个beanFactory,我们能拿到什么 int count = beanFactory.getBeanDefinitionCount(); // 我们能拿到有几个bean定义 String[] names = beanFactory.getBeanDefinitionNames(); // 除此之外,我们还能拿到每一个bean定义的名字 System.out.println("当前BeanFactory中有" + count + "个Bean"); System.out.println(Arrays.asList(names)); } }

注意,我们自己编写的MyBeanFactoryPostProcessor类要想让Spring知道,并且还要能被使用起来,那么它一定就得被加到容器中,为此,我们可以在其上标注一个@Component注解。

然后创建一个配置类,例如ExtConfig,在该配置类上使用@ComponentScan注解来配置包扫描。

package com.meimeixia.ext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.meimeixia.bean.Blue; @ComponentScan("com.meimeixia.ext") @Configuration public class ExtConfig { @Bean public Blue blue() { return new Blue(); } } package com.meimeixia.bean; public class Blue { public Blue() { System.out.println("blue...constructor"); } public void init() { System.out.println("blue...init..."); } public void destory() { System.out.println("blue...destory..."); } }

编写测试类

package com.meimeixia.test; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.meimeixia.ext.ExtConfig; public class IOCTest_Ext { @Test public void test01() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class); // 关闭容器 applicationContext.close(); } }

接下来测试下BeanFactoryPostProcessor的调用时机。

我们看到自己编写的BeanFactoryPostProcessor在Blue类的无参构造器创建Blue对象之前就已经工作了。我们看看到Blue组件注册到容器中的名字,只是此刻还没有创建对象。

说明BeanFactoryPostProcessor是在所有的bean定义信息都被加载之后才调用的。

源码分析

鼠标单击Eclipse左上角方法调用栈中的IOCTest_Ext.test01() line:12,这时程序来到了IOCTest_Ext类的test01方法中,如下图所示。

继续跟进代码,可以看到创建IOC容器时,最后还得刷新容器,如下图所示。

继续跟进代码,可以看到在刷新容器的过程中,还得执行在容器中注册的BeanFactoryPostProcessor(BeanFactory的后置处理器)的方法。

那具体是怎么来执行BeanFactoryPostProcessor的呢?我们继续跟进代码,发现又调用了一个invokeBeanFactoryPostProcessors方法,如下图所示。

下面我们来仔细分析一下PostProcessorRegistrationDelegate类中的invokeBeanFactoryPostProcessors方法具体都做了哪些操作。

会发现其遍历了所有的BeanFactoryPostProcessor组件,我们自己编写的实现了BeanFactoryPostProcessor接口的MyBeanFactoryPostProcessor类肯定也属于其中,所以会被遍历到,然后便会执行其postProcessBeanFactory方法。

小结

经过源码分析,我们可以得出这样一个结论:首先从IOC容器中找到所有类型是BeanFactoryPostProcessor的组件,然后再来执行它们其中的方法,而且是在初始化创建其他组件前面执行。

Spring中BeanFactoryPostProcessor注解原理如何解析?

为什么在初始化其他组件前面执行的呢,之前我们分析AOP原理是,bean的初始化是放在finishBeanFactoryInitialization(beanFactory)方法执行的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。

本文共计1304个文字,预计阅读时间需要6分钟。

Spring中BeanFactoryPostProcessor注解原理如何解析?

目录概述BeanFactoryPostProcessor的调用时机案例实践源码分析小结概述描述BeanFactoryPostProcessor的调用时机、案例实践、源码分析等。

案例实践以一个简单的Spring Boot项目为例,展示如何使用BeanFactoryPostProcessor。

源码分析分析BeanFactoryPostProcessor在Spring框架中的源码实现。

小结总结BeanFactoryPostProcessor的使用方法和注意事项。

概述Spring框架中的BeanFactoryPostProcessor是一个在Bean初始化之前被调用的接口,它允许我们在Bean定义之前修改BeanFactory。本节将介绍BeanFactoryPostProcessor的调用时机、案例分析、源码解析等。

BeanFactoryPostProcessor的调用时机在Spring容器初始化过程中,BeanFactoryPostProcessor会在BeanDefinitionRegistryPostProcessor接口的实现类(如PostProcessorRegistrationPostProcessor)之后被调用,但在Bean实例化之前。

案例实践以下是一个使用BeanFactoryPostProcessor的简单示例:

javaimport org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.stereotype.Component;

@Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 在这里修改BeanFactory,例如添加一个新的属性 beanFactory.getPropertyValues().add(newProperty, newValue); }}

源码分析在Spring框架中,BeanFactoryPostProcessor的调用是由AbstractApplicationContext类的refresh()方法控制的。以下是相关的源码片段:

javapublic void refresh() throws BeansException, IllegalStateException { // ... invokeBeanFactoryPostProcessors(beanFactory); // ...}

private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // ... List beanFactoryPostProcessors=beanFactory.getBeanFactoryPostProcessors(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } // ...}

小结通过使用BeanFactoryPostProcessor,我们可以修改BeanFactory,从而影响Spring容器的行为。了解其调用时机和实现原理对于深入理解Spring框架的运作机制非常重要。希望这些内容能够帮助大家更好地学习Spring。

目录
  • 概述
  • BeanFactoryPostProcessor的调用时机
  • 案例实践
  • 源码分析
  • 小结

概述

我们现在来学习一下Spring里面的一些扩展原理,希望大家通过这些原理的学习,对Spring里面的运行机制,包括其内部的工作原理,能有一个非常深刻的认识,为以后学习Spring里面的其他框架会有较大的帮助。

BeanFactoryPostProcessor的调用时机

BeanFactoryPostProcessor其实就是BeanFactory(创建bean的工厂)的后置处理器。

看到BeanFactoryPostProcessor会联想到BeanPostProcessor,之前说过它是bean的后置处理器,并且是在bean创建对象初始化前后进行拦截工作的。

看完接口上的描述后,我们可以指定BeanFactoryPostProcessor的调用时机。意思是在IOC容器的BeanFactory标准初始化完成之后,修改IOC容器里面的BeanFactory。

什么是标准初始化么?后面描述是所有的bean定义已经被加载了,但是还没有bean被初始化。

总结:BeanFactoryPostProcessor的调用时机是在BeanFactory标准化之后,我们可以定制、修改BeanFactory里面的一些内容,此时,所有的bean定义已经被加载到BeanFactory中了,但是bean的实例还没创建。

案例实践

首先编写一个类实现BeanFactoryPostProcessor接口。

package com.meimeixia.ext; import java.util.Arrays; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; @Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory..."); // 这个时候我们所有的bean还没被创建 // 但是我们可以看一下通过Spring给我们传过来的这个beanFactory,我们能拿到什么 int count = beanFactory.getBeanDefinitionCount(); // 我们能拿到有几个bean定义 String[] names = beanFactory.getBeanDefinitionNames(); // 除此之外,我们还能拿到每一个bean定义的名字 System.out.println("当前BeanFactory中有" + count + "个Bean"); System.out.println(Arrays.asList(names)); } }

注意,我们自己编写的MyBeanFactoryPostProcessor类要想让Spring知道,并且还要能被使用起来,那么它一定就得被加到容器中,为此,我们可以在其上标注一个@Component注解。

然后创建一个配置类,例如ExtConfig,在该配置类上使用@ComponentScan注解来配置包扫描。

package com.meimeixia.ext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.meimeixia.bean.Blue; @ComponentScan("com.meimeixia.ext") @Configuration public class ExtConfig { @Bean public Blue blue() { return new Blue(); } } package com.meimeixia.bean; public class Blue { public Blue() { System.out.println("blue...constructor"); } public void init() { System.out.println("blue...init..."); } public void destory() { System.out.println("blue...destory..."); } }

编写测试类

package com.meimeixia.test; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.meimeixia.ext.ExtConfig; public class IOCTest_Ext { @Test public void test01() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class); // 关闭容器 applicationContext.close(); } }

接下来测试下BeanFactoryPostProcessor的调用时机。

我们看到自己编写的BeanFactoryPostProcessor在Blue类的无参构造器创建Blue对象之前就已经工作了。我们看看到Blue组件注册到容器中的名字,只是此刻还没有创建对象。

说明BeanFactoryPostProcessor是在所有的bean定义信息都被加载之后才调用的。

源码分析

鼠标单击Eclipse左上角方法调用栈中的IOCTest_Ext.test01() line:12,这时程序来到了IOCTest_Ext类的test01方法中,如下图所示。

继续跟进代码,可以看到创建IOC容器时,最后还得刷新容器,如下图所示。

继续跟进代码,可以看到在刷新容器的过程中,还得执行在容器中注册的BeanFactoryPostProcessor(BeanFactory的后置处理器)的方法。

那具体是怎么来执行BeanFactoryPostProcessor的呢?我们继续跟进代码,发现又调用了一个invokeBeanFactoryPostProcessors方法,如下图所示。

下面我们来仔细分析一下PostProcessorRegistrationDelegate类中的invokeBeanFactoryPostProcessors方法具体都做了哪些操作。

会发现其遍历了所有的BeanFactoryPostProcessor组件,我们自己编写的实现了BeanFactoryPostProcessor接口的MyBeanFactoryPostProcessor类肯定也属于其中,所以会被遍历到,然后便会执行其postProcessBeanFactory方法。

小结

经过源码分析,我们可以得出这样一个结论:首先从IOC容器中找到所有类型是BeanFactoryPostProcessor的组件,然后再来执行它们其中的方法,而且是在初始化创建其他组件前面执行。

Spring中BeanFactoryPostProcessor注解原理如何解析?

为什么在初始化其他组件前面执行的呢,之前我们分析AOP原理是,bean的初始化是放在finishBeanFactoryInitialization(beanFactory)方法执行的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。