这篇文章主要介绍了Spring5源码之BeanPostProcessor的接口,这是Spring中开放式架构中一个必不可少的亮点,给用户充足的权限去更改或者扩展Spring,需要的朋友可以参考一下。
1、BeanPostProcessor接口
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;
/**
* Factory hook that allows for custom modification of new bean instances,
* e.g. checking for marker interfaces or wrapping them with proxies.
*
* <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
* bean definitions and apply them to any beans subsequently created.
* Plain bean factories allow for programmatic registration of post-processors,
* applying to all beans created through this factory.
*
* <p>Typically, post-processors that populate beans via marker interfaces
* or the like will implement {@link #postProcessBeforeInitialization},
* while post-processors that wrap beans with proxies will normally
* implement {@link #postProcessAfterInitialization}.
*
* @author Juergen Hoeller
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*/
public interface BeanPostProcessor {
源码定义:工厂挂钩,允许用户自定义修改新的bean实例,例如:检查标记接口或用代理包装它们。
2、实现BeanPostProcessor接口的案例
- 普通的bean:Dog
package com.test.bean;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Data
@Slf4j
public class Dog {
private String name;
private Integer age;
public void print() {
log.info("dog name:{} age:{}", name, age);
}
}
- 实现BeanPostProcessor接口的bean:DogBeanPostProcessor
package com.test.processor;
import com.test.bean.Dog;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @Description: 自定义DogBeanPostProcessor
* @Author: Janson
* @Date: 2020/4/6 15:40
**/
public class DogBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return dealWithDog(bean, true);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return dealWithDog(bean, false);
}
private Object dealWithDog(Object bean, boolean isBefore) {
if (bean instanceof Dog) {
Dog dog = (Dog) bean;
if (!isBefore) {
dog.setName("SIBERIAN HUSKY");
dog.setAge(2);
}
dog.print();
return bean;
}
return bean;
}
}
- resources目录下配置的xml文件:bean.xml
<?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 id="dog" class="com.test.bean.Dog">
<property name="name" value="Hello Dog"></property>
<property name="age" value="1"></property>
</bean>
<bean id="dogBeanPostProcessor" class="com.test.processor.DogBeanPostProcessor"></bean>
</beans>
- 测试类BeanPostProcessorTest
package com.test;
import com.test.bean.Dog;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Description: BeanPostProcessor测试类
* @Author: Janson
* @Date: 2020/4/6 15:40
**/
public class BeanPostProcessorTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
Dog dog = (Dog) applicationContext.getBean("dog");
}
}
- 程序执行可以看到如下的结果:
16:58:52.886 [main] INFO com.test.bean.Dog - dog name:Hello Dog age:1
16:58:52.887 [main] INFO com.test.bean.Dog - dog name:SIBERIAN HUSKY age:2
- 总结:从程序的执行结果可以看到两点:
1、我们在前处理器postProcessBeforeInitialization方法中输出我们初始化定义的Dog属性为name:Hello Dog age:1。
2、我们通过自定义的处理器DogBeanPostProcessor在postProcessAfterInitialization方法对Dog类中的原始属性name和age进行了修改,输出我们修改的结果为dog name:SIBERIAN HUSKY age:2。
3、源码AbstractAutowireCapableBeanFactory的实现
- 初始化bean的方法initializeBean
/**
* 初始化bean的方法
**/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// 初始化bean之前
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用初始化方法初始化bean
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 初始化bean之后
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
- 初始化bean的方法调用前处理器applyBeanPostProcessorsBeforeInitialization
/**
* 初始化bean的方法调用前
*/
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 调用自定义的postProcessBeforeInitialization方法
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
- 初始化bean的方法调用后处理器applyBeanPostProcessorsAfterInitialization
/**
* 初始化bean方法调用后
*/
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 调用自定义的postProcessAfterInitialization方法
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
如果您觉得有帮助,欢迎点赞哦 ~ ~ 多谢~ ~