简介
注意:我使用的是SpringBoot版本:2.5.3
BeanPostProcessor包括二个初始化相关方法,InstantiationAwareBeanPostProcessor:包括这个实例化相关方法,以及一个属性值相关方法,postProcessProperties(postProcessPropertyValues在此版本中被标记为过时)
先整体看一下,这个五个方法执行的顺序,如流程图
测试例子
相关文件
<?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.szh.quartzx.User" id="user" init-method="start">
<property name="name" value="波波烤鸭"></property>
</bean>
<bean class="com.szh.quartzx.MyInstantiationBeanPostProcessor"/>
</beans>
User 对象
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("自定义初始化的方法....");
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", beanName=" + beanName + "]";
}
}
MyInstantiationBeanPostProcessor
public class MyInstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
// 初始化方法-before
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(">>postProcessBeforeInitialization---初始化方法--对象已经存在了");
return bean;
}
// 初始化-after
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("<<postProcessAfterInitialization -- 在Bean的自定义初始化方法执行完成之后执行--对象已经存在");
return bean;
}
/**
* 在实例化之前调用,如果返回null,一切按照正常顺序执行,如果返回的是一个实例的对象,那么这个将会跳过实例化、初始化的过程
* @param beanClass
* @param beanName
* @return
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("--->postProcessBeforeInstantiation ---在方法实例化之前执行 Bean对象还没有");
// 利用cglib生成代理对象
if (beanClass == User.class){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanClass);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// System.out.println("方法执行之前:"+method);
Object object = methodProxy.invokeSuper(o, objects);
// System.out.println("方法执行之后:+"+method);
return object;
}
});
User user = (User) enhancer.create();
// 返回代理类
return user;
}
return null;
}
/**
* 在实例化之后,postProcessBeforeInitialization之前执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("<---postProcessAfterInstantiation --在方法实例化之后执行 Bean对象已经创建出来了");
return true;
}
/**
* 实例化之后调用,属性填充之前
* @param pvs PropertyValues对象,用于封装指定类的对象,简单来说就是PropertyValue的集合,里面相当于以key-value形式存放类的属性和值
* @param pds PropertyDescriptor对象数组,PropertyDescriptor相当于存储类的属性,不过可以调用set,get方法设置和获取对应属性的值
* @param bean 当前的bean
* @param beanName beanName
* @return 如果返回null,那么将不会进行后续的属性填充,比如依赖注入等,如果返回的pvs额外的添加了属性,那么后续会填充到该类对应的属性中。
*/
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
String beanName) throws BeansException {
System.out.println("<---postProcessPropertyValues--可以用来修改Bean中属性的内容->");
return pvs;
}
}
测试类
@Test
public void test1() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = ac.getBean(User.class);
System.out.println(user);
// 关闭销毁
ac.registerShutdownHook();
}
根据是否返回 BeforeInstant 是否返回null,有二种情况
// 返回null
--->postProcessBeforeInstantiation ---在方法实例化之前执行 Bean对象还没有
执行了构造方法------》User 被实例化
<---postProcessAfterInstantiation --在方法实例化之后执行 Bean对象已经创建出来了
<---postProcessPropertyValues--可以用来修改Bean中属性的内容->
开始设置属性喽:设置:波波烤鸭
>>postProcessBeforeInitialization---初始化方法--对象已经存在了
自定义初始化的方法....
<<postProcessAfterInitialization -- 在Bean的自定义初始化方法执行完成之后执行--对象已经存在
User [id=0, name=波波烤鸭, beanName=null]
// 不返回null
--->postProcessBeforeInstantiation ---在方法实例化之前执行 Bean对象还没有
执行了构造方法------》User 被实例化
<<postProcessAfterInitialization -- 在Bean的自定义初始化方法执行完成之后执行--对象已经存在
User [id=0, name=null, beanName=null]
源码解析
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation
* 作用:在实例化之前解析是否有快捷创建的Bean,就是通过postProcessBeforeInstantiation返回的Bean
*/
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//调用方法,内部遍历调用postProcessBeforeInstantiation方法【在实例化之前调用】
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//如果返回了快捷的Bean
if (bean != null) {
//如果postProcessBeforeInstantiation方法返回了快捷的Bean,内部遍历调用postProcessBeforeInstantiation方法【在初始化之后调用】
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation
* 作用:调用postProcessBeforeInstantiation方法
*/
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
//遍历所有的后置处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断是否是InstantiationAwareBeanPostProcessor类型的,如果是的,调用postProcessBeforeInstantiation方法获取快捷Bean
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization
* 作用:遍历调用postProcessAfterInitialization
*/
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
populateBean 执行的时刻是:实例化之后调用,在方法applyPropertyValues【属性填充】之前
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean
* 填充指定Bean的属性
* 在该方法内部遍历所有的BeanPostPorcessor,调用postProcessAfterInstantiation方法
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
//获取属性
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
//判断ioc容器中是否存在InstantiationAwareBeanPostProcessors(
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//遍历所有的InstantiationAwareBeanPostProcessor
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 执行 postProcessPropertyValues 设置值
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
//重要的一步,设置属性
applyPropertyValues(beanName, mbd, bw, pvs);
}