spring的BeanPostProcessor分析

1:作用

在spring bean的生命周期中加入自定义逻辑。

2:接口

源码:

public interface BeanPostProcessor {
	// 该方法在调用完毕构造方法,setter方法后,执行init-method方法前
	// 执行,参数为当前状态下的bean,以及bean的名称
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	// 该方法在init-method方法调用完毕后执行
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

2:例子

在BeanFactory中不会自动注册自定义的BeanPostProcessor,需要通过API添加,但是在ApplicationContext体系中会自动检测并添加调用。

2.1:定义Bean

public class User {
	private int id;
	private String name;
	private String beanName;
	
	public User() {
		System.out.println("User 被实例化");
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		System.out.println("设置:"+name);
		this.name = name;
	}

	public String getBeanName() {
		return beanName;
	}

	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}
	/**
	 * 自定义的初始化方法
	 */
	public void start() {
		System.out.println("User 中自定义的初始化方法");
	}
}

2.2:定义自定义后置bean处理器

public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("before--实例化的bean对象:"+bean+"\t"+beanName);
		// 可以根据beanName不同执行不同的处理操作
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("after...实例化的bean对象:"+bean+"\t"+beanName);
		// 可以根据beanName不同执行不同的处理操作
		return bean;
	}
}

2.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="yudaosourcecode.postprocessor.User" id="user" init-method="start">
        <property name="name" value="波波烤鸭" />
    </bean>

    <!-- 注册处理器 -->
    <bean class="yudaosourcecode.postprocessor.MyBeanPostProcessor"/>
</beans>

2.5:ApplicationContext测试

@Test
public void testBeanDefinitionWithApplicationContext() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("testbeandefinition.xml");
    ac.getBean(User.class);
}

运行:

User 被实例化
设置:波波烤鸭
before--实例化的bean对象:yudaosourcecode.postprocessor.User@28ac3dc3	user
User 中自定义的初始化方法
after...实例化的bean对象:yudaosourcecode.postprocessor.User@28ac3dc3	user

可以看到程序的执行顺序为”构造函数->setter->BeanPostProcessor#postProcessBeforeInitialization->init-method->BeanPostProcessor#postProcessAfterInitialization“,从这个执行顺序基本可以得出结论,这里的post是相对于构造函数来说的,即在构造函数之后,initiallization指的是init-method。从结果可以看到,ApplicationContext确实自动注册了,源码如下:

org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
	this(new String[] {configLocation}, true, null);
}
org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

	...snip...
	if (refresh) {
		refresh();
	}
}
org.springframework.context.support.AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		...snip...
		try {
			...snip...
			// 注册用于拦截处理bean创建的BeanPostProcessor
			registerBeanPostProcessors(beanFactory);
			...snip...
		}
	}
}
org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
	// 获取bean工厂容器中所有的BeanPostProcessor实例的名称
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// BeanPostProcessor的总个数
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	// 注册BeanPostProcessorChecker类型的BeanPostProcessor
	// 执行日志记录相关内容
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// 存储通过PriorityOrder接口的BeanPostProcessor
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	// 记录MergedBeanDefinitionPostProcessor类型的BeanPostProcessor
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	// 记录实现了Order接口的BeanPostProcessor
	List<String> orderedPostProcessorNames = new ArrayList<>();
	// 记录既没有实现PriorityOrdered接口也没有实现Ordered接口的BeanPostProcessor
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		// 如果是PriorityOrder类型,则添加到priorityOrderedPostProcessors
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			// 如果是MergedBeanDefinitionPostProcessor类型则添加到
			// internalPostProcessors
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		// 如果是Ordered接口类型,则添加到orderedPostProcessorNames
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		// 否则,添加到nonOrderedPostProcessorNames
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// 排序实现了PriorityOrdered接口的BeanPostProcessor
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	// 注册实现了PriorityOrdered接口的BeanPostProcessor,调用AbstractBeanFacotry#addBeanPostProcesssor
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// 根据名称获取实现了Ordered接口的BeanPostProcessor
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 排序实现了Oredered接口的BeanPostProcessor
	sortPostProcessors(orderedPostProcessors, beanFactory);
	// 注册实现了Ordered接口的BeanPostProcessor,调用AbstractBeanFacotry#addBeanPostProcesssor
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// 获取所有的即没有实现Ordered接口,也没有实现PriorityOrdered接口的
	// 普通的BeanPostProcesssor实例
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 注册普通BeanPostProcessor,调用AbstractBeanFacotry#addBeanPostProcesssor
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// 排序所有的MergeBeanDefinitionPostProcessor类型的BeanPostProcessor
	sortPostProcessors(internalPostProcessors, beanFactory);
	// 注册所有的MergeBeanDefinitionPostProcessor类型的BeanPostProcessor,调用AbstractBeanFacotry#addBeanPostProcesssor
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

3:InstantiationAwareBeanPostProcessor

这是BeanPostProcessor的一个子接口,翻译过来是实例化感知的bean后置处理器,大概意思就是在通过构造函数创建实例对象的前后加入一些操作,其实就是扩展了BeanPostProcessor的功能,接口定义如下:

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
	// 在调用构造方法之前,执行该方法,分为以下两种情况
	// 1:如果是不想要默认生成的对象,则可以在这里创建,然后返回
	// 2:如果是不想干预默认对象的生成,则直接返回null即可
	// 一般这里我们都会返回null,default实现也是返回null,因此,
	// 在实际使用中可以忽略该方法,不需要实现
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
	// 该方法在构造函数执行之后执行,分为以下两种情况
	// 1:如果是希望后续继续填充属性信息,则返回true
	// 2:如果是不希望填充属性信息,则返回false
	// 正常都是返回true,这里的default实现也是如此,因此,
	// 在实际使用中可以忽略该方法,不需要是实现
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}
	// 暂时忽略
	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

	// 在填充属性之前执行,最后一次修改属性信息的机会
	// 如果是希望修改属性信息,则可以在这里完成,否则
	// 直接返回传入参数中的ProperyValues就可以了
	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}

}

3.1:定义Bean

public class User {
	private int id;
	private String name;
	private String beanName;
	
	public User() {
		System.out.println("User 被实例化");
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		System.out.println("设置:"+name);
		this.name = name;
	}

	public String getBeanName() {
		return beanName;
	}

	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}
	/**
	 * 自定义的初始化方法
	 */
	public void start() {
		System.out.println("User 中自定义的初始化方法");
	}
}

3.2:定义自定义后置bean处理器

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	/**
	 * BeanPostProcessor接口中的方法
	 * 在Bean的自定义初始化方法之前执行
	 * Bean对象已经存在了
	 */
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println(">>postProcessBeforeInitialization");
		return bean;
	}

	/**
	 * BeanPostProcessor接口中的方法
	 * 在Bean的自定义初始化方法执行完成之后执行
	 * Bean对象已经存在了
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("<<postProcessAfterInitialization");
		return bean;
	}

	/**
	 * InstantiationAwareBeanPostProcessor中自定义的方法
	 * 在方法实例化之前执行  Bean对象还没有
	 */
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		System.out.println("--->postProcessBeforeInstantiation");
		return null;
	}

	/**
	 * InstantiationAwareBeanPostProcessor中自定义的方法
	 * 在方法实例化之后执行  Bean对象已经创建出来了
	 */
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		System.out.println("<---postProcessAfterInstantiation");
		return true;
	}

	/**
	 * InstantiationAwareBeanPostProcessor中自定义的方法
	 * 可以用来修改Bean中属性的内容
	 */
	@Override
	public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
													String beanName) throws BeansException {
		System.out.println("<---postProcessPropertyValues--->");
		return pvs;
	}
}

3.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="yudaosourcecode.postprocessor.User" id="user" init-method="start">
        <property name="name" value="波波烤鸭" />
    </bean>

    <!-- 注册处理器 -->
    <bean class="yudaosourcecode.postprocessor.MyInstantiationAwareBeanPostProcessor"/>
</beans>

3.4:ApplicationContext测试

@Test
public void testBeanPostProcessor() {
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("testbeandefinition.xml");
    ac.getBean("user");
}

运行:


--->postProcessBeforeInstantiation
User 被实例化
<---postProcessAfterInstantiation
<---postProcessPropertyValues--->
设置:波波烤鸭
>>postProcessBeforeInitialization
User 中自定义的初始化方法
<<postProcessAfterInitialization

相比于BeanPostProcessor多了,实例化前,实例化后,属性设置前这三个干预bean创建的方法。我们来看对比下二者的执行情况:

执行时期BeanPostProcessorInstantiationAwareBeanPostProcessor
实例化前不支持postProcessBeforeInstantiation
实例化后不支持postProcessAfterInstantiation
属性设置前不支持postProcessPropertyValues
初始化方法前postProcessBeforeInitializationpostProcessBeforeInitialization
初始化方法前postProcessAfterInitializationpostProcessAfterInitialization
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值