Spring之BeanFactoryPostProcessor接口介绍

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的区别。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序生活

Leetcode-Medium 11. Container With Most Water

假设有一个数组a1,a2,a3.....,其中a1和a20组成的容器容量最大。容量计算公式maxa=max((right-left)min(height[lef...

10020
来自专栏编程坑太多

『互联网架构』软件架构-spring源码之spring结构概述(八)

spring-core和spring-beans模块是[Spring框架的基础],包括控制反转和依赖注入等功能。BeanFactory是工厂模式的微妙实现,它移...

13830
来自专栏marsggbo

大白话Docker入门(一)

随着docker现在越来越热门,自己也对docker的好奇心也越来越重,终于忍不住利用了一些时间把docker学习一遍。目前的资料不少,但是由于docker的发...

11340
来自专栏FreeBuf

快速推进DevOps流程时的安全问题探讨

容器和微服务技术的诞生为我们设计和构建安全的基础设施以及应用程序提供了非常大的帮助。容器环境从中心化到数字化的转变,正在迅速成为主流。基于云环境的原生架构以及基...

10920
来自专栏marsggbo

【转载】大白话Docker入门(二)

上篇的大白话Docker入门(一)让我们认识了docker,知道docker大概是怎么玩的。初步的印象可能会让你觉得和现在的VM的部署方式也挺像的,比如dock...

11430
来自专栏编程坑太多

『互联网架构』软件架构-spring源码之spring ioc(九)

PS:读源码确实很麻烦,但是spring的源码大概120多MB,相当于一个JAVA的JDK了,读了怼咱们日常开发真的很有用,设计到的模式:单例模式,工厂模式,建...

9530
来自专栏生信技能树

如何从看不懂Dockerfile到创建自己的镜像

开始了解Docker是健明的一篇文章跟着jimmy学docker系列之第2讲:一个软件一个容器,那时正在研究虚拟机(Virtual Machine),发现Doc...

37120
来自专栏云计算D1net

容器管理的8个顶级解决方案

对于选择容器管理解决方案的组织来说,了解给定的解决方案以及提供该解决方案的供应商是很重要的。这是因为每个容器管理提供商的产品都提供了各种功能和工具,这些功能和工...

14840
来自专栏性能与架构

架构设计 - 隔离术

隔离是通过将系统、资源分开,从而保证在发生问题时使其影响最小化,防止出现雪崩效应。

17420
来自专栏LeetCode

jsp编译、执行过程

https://blog.csdn.net/napoay/article/details/50755064

24730

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励