0. 前言
之所以在企业级应用中Spring 到Spring Boot 一直立于不败之地,保持火热,其中很关键的一个点是,它的扩展简直太强大了,上一篇,我们聊了一下 Spring Boot整个生命周期中的扩展点,,比如SpringApplicationRunListener
可以监听应用的各个阶段。本文我们聊聊,Spring 容器上的扩展。可用于自定义和扩展 Spring 容器的行为。其中,三个常见的容器扩展接口是 BeanFactoryPostProcessor
、BeanPostProcessor
和 BeanDefinitionRegistryPostProcessor
。通过实现这些接口,开发者可以自定义 Spring 容器的行为,从而更好地满足应用程序的需求。
下面我们分别聊聊这三种的Spring 容器相关的扩展接口加载时机,原理,以及使用方式。帮助大家更好地理解 Spring Boot 中的容器扩展。
-
BeanFactoryPostProcessor
接口可以在 Spring 容器实例化 Bean 对象之前修改 Bean 的配置元数据。 -
BeanPostProcesso
r 接口可以在 Spring 容器实例化 Bean 对象之后对 Bean 进行一些自定义操作。 -
BeanDefinitionRegistryPostProcessor
接口可以在 Spring 容器实例化 Bean 对象之前修改 Bean 的配置元数据,并向容器中添加新的 Bean 定义。
冰点出品,必属精品
1. 容器扩展接口
Spring的可扩展性非常强大,其中的一个重要原因就是它提供了许多的PostProcessor,开发人员可以通过这些接口来对Spring容器中的Bean进行自定义的处理和增强。
其中,BeanFactoryPostProcessor 接口对应着 BeanFactory,它主要用于处理 BeanDefinition,也就是 Bean 的定义信息,包括 Bean 的类型、作用域、依赖关系等等。BeanFactoryPostProcessor 在 Bean 实例化之前执行,它可以修改 BeanDefinition 的配置信息,从而影响 Bean 的实例化过程。
与之不同的是,BeanPostProcessor 接口主要用于对 Bean 实例进行处理和增强。它在 Bean 实例化之后执行,可以对 Bean 进行各种自定义操作,例如添加代理、修改属性值等等。
如下图
此图来自网络
2. 使用场景示例
1. BeanFactoryPostProcessor
BeanFactoryPostProcessor 是 Spring 容器提供的一个扩展接口,用于在 Spring 容器实例化 Bean 对象之前修改 Bean 的配置元数据。在 Spring 容器初始化的过程中,当容器读取完 Bean 定义信息后,就会调用 BeanFactoryPostProcessor 接口的实现类的 postProcessBeanFactory() 方法。在该方法中,开发者可以通过 BeanDefinitionRegistry 来获取和修改 Bean 的配置元数据。
BeanFactoryPostProcessor 接口定义了一个方法 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory),其中 ConfigurableListableBeanFactory 是一个 Bean 工厂的配置接口,定义了对 Bean 工厂的一些配置方法。通过实现该接口,开发者可以获取到 Bean 工厂的配置信息,并对 Bean 工厂中的 Bean 进行修改。
下面是一个示例,该示例在 Bean 实例化之前将所有 Bean 定义的 scope 属性设置为 prototype
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
}
}
}
在该示例中,我们实现了 BeanFactoryPostProcessor 接口,并在 postProcessBeanFactory() 方法中获取了 Bean 工厂的所有 Bean 定义,然后将它们的 scope 属性设置为 prototype,从而将它们的作用域修改为原型作用域。
2. BeanPostProcessor
BeanPostProcessor 是 Spring 容器提供的另一个扩展接口,用于在 Spring 容器实例化 Bean 对象之后对 Bean 进行一些自定义操作。在 Spring 容器初始化的过程中,当容器实例化一个 Bean 对象后,就会调用 BeanPostProcessor 接口的实现类的 postProcessBeforeInitialization() 方法和 postProcessAfterInitialization() 方法。在这两个方法中,开发者可以对 Bean 对象进行一些自定义操作。
BeanPostProcessor 接口定义了两个方法:
/**
* 用于在 Bean 初始化之前对其进行处理。具体来说,该方法将在任何 Bean 的初始化回调方法(例如 InitializingBean 的
* afterPropertiesSet 方法或自定义的 init 方法)之前调用。在此之前,Bean 已经被实例化并填充了属性值。
* 该方法允许对 Bean 进行自定义处理,例如添加代理、修改属性值等等。该方法的返回值是一个 Bean 实例,
* 可以是原始的 Bean 实例或者是一个代理实例,如果返回 null,则表示不对该 Bean 进行处理。
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* 该方法将在任何 Bean 的初始化回调方法(例如 InitializingBean 的 afterPropertiesSet 方法或自定义的
* init 方法)之后调用。在此之后,Bean 已经被完全初始化,可以进行各种操作。
* 该方法允许对 Bean 进行自定义处理,例如添加代理、修改属性值等等。
* 该方法的返回值是一个 Bean 实例,可以是原始的 Bean 实例或者是一个代理实例
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
下面是项目中的一个真实实例,强制性的给所有引入此组件的工程都注入一个默认属性。
/**
* MybatisPlusProperties创建时添加默认配置
*/
public class ExtendFieldTypeHandlerPostProcessor implements BeanPostProcessor {
/**
* bean初始化前,动态添加配置
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//判断当前初始化bean是MybatisPlusProperties
if (bean instanceof MybatisPlusProperties) {
MybatisPlusProperties mybatisPlusProperties = (MybatisPlusProperties) bean;
mybatisPlusProperties.setTypeHandlersPackage("com.xxx.common.typeHandler");
return mybatisPlusProperties;
}
return bean;
}
}
}
3. BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor 是 Spring 容器提供的另一个扩展接口,用于在 Spring 容器实例化 Bean 对象之前修改 Bean 的配置元数据。与 BeanFactoryPostProcessor 不同的是,BeanDefinitionRegistryPostProcessor 可以向 Spring 容器中添加新的 Bean 定义。
在 Spring 容器初始化的过程中,当容器读取完 Bean 定义信息后,就会调用 BeanDefinitionRegistryPostProcessor 接口的实现类的 postProcessBeanDefinitionRegistry() 方法。在该方法中,开发者可以通过 BeanDefinitionRegistry 接口来获取和修改 Bean 的配置元数据,并向容器中添加新的 Bean 定义。
BeanDefinitionRegistryPostProcessor 接口定义了一个方法 postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry),其中 BeanDefinitionRegistry 是一个 Bean 定义注册的接口,定义了向容器中注册 Bean 定义的方法。通过实现该接口,开发者可以获取到 Bean 定义注册器的信息,并向容器中添加新的 Bean 定义。
下面是一个示例,该示例在 Bean 实例化之前向容器中添加一个新的 Bean 定义:
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(CustomBean.class)
.addPropertyValue("name", "Custom Bean")
.getBeanDefinition();
registry.registerBeanDefinition("customBean", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
实现了 BeanDefinitionRegistryPostProcessor 接口,并在 postProcessBeanDefinitionRegistry() 方法中向容器中添加了一个名为 customBean 的新的 Bean 定义。文章来源:https://www.toymoban.com/news/detail-676995.html
3. 参考文档
- Spring Boot官方文档:https://spring.io/projects/spring-boot
- Spring Boot Reference Guide:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/
- Spring Boot官方文档相关 https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-customizing-bean-definitions
- Spring Boot 自动配置 https://docs.spring.io/spring-boot/docs/3.1.2/reference/html/auto-configuration-classes.html#appendix.auto-configuration-classes
文章来源地址https://www.toymoban.com/news/detail-676995.html
到了这里,关于Spring Boot 容器扩展BeanFactoryPostProcessor、BeanPostProcessor、 BeanDefinitionRegistryPostProcessor用法和解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!