Spring之BeanFactoryPostProcessor接口介绍

简介: Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义BeanFactoryPostProcessor,通过设置’order’属性来确定各个BeanFactoryPostProcessor执行顺序。


 在前一篇文章Spring之BeanPostProcessor(后置处理器)介绍的基础上我们来介绍BeanFactoryPostProcessor接口,从名字上来看很相似,但他们的作用确不尽相同。

文章目录

   BeanFactoryPostProcessor

       1.BeanFactoryPostProcessor接口内容

       2.自定义BeanFactoryPostProcessor 实现类

       3.配置文件中注册

       4.测试

BeanFactoryPostProcessor

  Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义BeanFactoryPostProcessor,通过设置’order’属性来确定各个BeanFactoryPostProcessor执行顺序。

  注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别,案例代码在上篇文章的基础上验证。

1.BeanFactoryPostProcessor接口内容

public interface BeanFactoryPostProcessor {
  /**
   * Modify the application context's internal bean factory after its standard
   * initialization. All bean definitions will have been loaded, but no beans
   * will have been instantiated yet. This allows for overriding or adding
   * properties even to eager-initializing beans.
   * @param beanFactory the bean factory used by the application context
   * @throws org.springframework.beans.BeansException in case of errors
   */
  void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

2.自定义BeanFactoryPostProcessor 实现类

/**
 * 自定义BeanFactoryPostProcessor
 * 
 * @author dengp
 *
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  /**
   * 本方法在Bean对象实例化之前执行,
   * 通过beanFactory可以获取bean的定义信息,
   * 并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别
   */
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    System.out.println(">> BeanFactoryPostProcessor 开始执行了");
    String[] names = beanFactory.getBeanDefinitionNames();
    for (String name : names) {
      if("user".equals(name)){
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
        MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
        // MutablePropertyValues如果设置了相关属性,可以修改,如果没有设置则可以添加相关属性信息
        if(propertyValues.contains("name")){
          propertyValues.addPropertyValue("name", "bobo");
          System.out.println("修改了属性信息");
        }
      }
    }
    System.out.println(">> BeanFactoryPostProcessor 执行结束");
  }
}

3.配置文件中注册

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean class="com.dpb.pojo.User" id="user" init-method="start">
    <property name="name" value="波波烤鸭"></property>
  </bean>
  <!-- 注册处理器 -->
  <bean class="com.dpb.processor.MyBeanPostProcessor"/>
  <!-- 注册BeanFactoryPostProcessor -->
  <bean class="com.dpb.factoryprocessor.MyBeanFactoryPostProcessor"></bean>
</beans>

4.测试

@Test
public void test1() {
  ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  User user = ac.getBean(User.class);
  System.out.println(user);
}

输出结果

>> BeanFactoryPostProcessor 开始执行了
修改了属性信息
>> BeanFactoryPostProcessor 执行结束
User 被实例化
设置:bobo
A before--实例化的bean对象:User [id=0, name=bobo, beanName=null]  user
User 中自定义的初始化方法
A after...实例化的bean对象:User [id=0, name=bobo, beanName=null]  user
User [id=0, name=bobo, beanName=null]

总结:从输出结果我们可以看出postProcessBeanFactory方法执行的顺序是在Bean实例化之前。可以修改Bean的属性值【波波烤鸭改为bobo】。从这儿也能看出BeanFactoryPostProcessor和BeanPostProcessor的区别。


相关文章
|
7天前
|
Java API 微服务
【Spring Boot系列】通过OpenAPI规范构建微服务服务接口
【4月更文挑战第5天】通过OpenAPI接口构建Spring Boot服务RestAPI接口
|
1月前
|
传感器 Java API
Spring揭秘:Aware接口应用场景及实现原理!
Aware接口赋予了Bean更多自感知的能力,通过实现不同的Aware接口,Bean可以轻松地获取到Spring容器中的其他资源引用,像ApplicationContext、BeanFactory等。 这样不仅增强了Bean的功能,还提高了代码的可维护性和扩展性,从而让Spring的IoC容器变得更加强大和灵活。
127 0
Spring揭秘:Aware接口应用场景及实现原理!
|
1月前
ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao
ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao
8 0
|
1月前
|
Java Spring
使用JDBCTemplate实现与Spring结合,方法公用 ——接口(BaseDao)
使用JDBCTemplate实现与Spring结合,方法公用 ——接口(BaseDao)
9 0
|
1月前
|
存储 Java 数据处理
Spring揭秘:ClassPathScanningProvider接口应用场景及实现原理!
ClassPathScanningCandidateComponentProvider是Spring框架中一个非常核心的类,它主要用于在类路径下扫描并发现带有特定注解的组件,支持诸如@ComponentScan、@Component、@Service、@Repository和@Controller等注解的自动扫描和注册。
Spring揭秘:ClassPathScanningProvider接口应用场景及实现原理!
|
1月前
|
Java API 开发者
Spring揭秘:BeanDefinitionBuilder接口应用场景及实现原理!
BeanDefinitionBuilder类为Spring框架中的Bean定义提供了灵活且强大构建方式,通过API,开发者能够轻松创建和配置Bean,无需依赖繁琐的XML配置或注解。
Spring揭秘:BeanDefinitionBuilder接口应用场景及实现原理!
|
1月前
|
Java API 对象存储
Spring揭秘:AnnotationMetadata接口应用场景及实现原理!
AnnotationMetadata接口可以轻松获取类、方法或字段上的注解信息,简化注解处理,提供一致且灵活的访问方式,支持运行时处理,让开发者能更专注于业务逻辑而非底层细节,从而加速开发进程。
Spring揭秘:AnnotationMetadata接口应用场景及实现原理!
|
1月前
|
存储 Java API
Spring揭秘:Environment接口应用场景及实现原理!
Environment接口提供了强大且灵活的环境属性管理能力,通过它,开发者能轻松地访问和配置应用程序运行时的各种属性,如系统属性、环境变量等。 同时,Environment接口还支持属性源的定制和扩展,使得开发者能根据实际需求灵活地定制属性的加载和解析方式。
Spring揭秘:Environment接口应用场景及实现原理!
|
1月前
|
安全 Java API
Spring Boot 接口规范如何遵守?
【2月更文挑战第17天】
55 4
Spring Boot 接口规范如何遵守?
|
1月前
|
缓存 前端开发 Java
【Spring底层原理高级进阶】轻松掌握 Spring MVC 的拦截器机制:深入理解 HandlerInterceptor 接口和其实现类的用法
【Spring底层原理高级进阶】轻松掌握 Spring MVC 的拦截器机制:深入理解 HandlerInterceptor 接口和其实现类的用法