InstantiationAwareBeanPostProcessor 接口继承了 BeanPostProcessor 接口。
BeanPostProcessor 主要是在 Bean 调用初始化方法前后进行拦截。
而 InstantiationAwareBeanPostProcessor 接口在 BeanPostProcessor 基础上添加了对 bean 的创建前后,以及设置属性前进行拦截。
它的方法如下:
方法 | 执行顺序 | 备注 |
---|---|---|
postProcessBeforeInstantiation() | 在 Bean 创建前调用 | 可用于创建代理类,如果返回的不是 null(也就是返回的是一个代理类) ,那么后续只会调用 postProcessAfterInitialization() 方法 |
postProcessAfterInstantiation() | 在 Bean 创建后调用 | 返回值会影响 postProcessProperties() 是否执行,其中返回 false 的话,是不会执行。 |
postProcessProperties() | 在 Bean 设置属性前调用 | 用于修改 bean 的属性,如果返回值不为空,那么会更改指定字段的值 |
postProcessBeforeInitialization() | 在 Bean 调用初始化方法前调用 | 允许去修改 bean 实例化后,没有调用初始化方法前状态的属性 |
postProcessAfterInitialization() | 在 Bean 调用初始化方法后调用 | 允许去修改 bean 调用初始化方法后状态的属性 |
验证
TestBean 类
public class TestBean implements InitializingBean {
protected Object field;
public TestBean() {
System.out.println("创建 TestBean 对象");
}
public Object getField() {
return field;
}
public void setField(Object field) {
System.out.println("设置 field 属性");
this.field = field;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("调用初始化方法");
}
@Override
public String toString() {
return "TestBean{" +
"field=" + field +
'}';
}
}
InstantiationAwareBeanPostProcessor 类
/**
* InstantiationAwareBeanPostProcessor 的实现类
*/
public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if(isMatchClass(beanClass)){
System.out.println("调用 postProcessBeforeInstantiation 方法");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if(isMatchClass(bean.getClass())){
System.out.println("调用 postProcessAfterInstantiation 方法");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if(isMatchClass(bean.getClass())){
System.out.println("调用 postProcessProperties 方法");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(isMatchClass(bean.getClass())){
System.out.println("调用 postProcessBeforeInitialization 方法");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(isMatchClass(bean.getClass())){
System.out.println("调用 postProcessAfterInitialization 方法");
}
return bean;
}
private boolean isMatchClass(Class<?> beanClass){
// ClassUtils 类为 org.springframework.util.ClassUtils
return TestBean.class.equals(ClassUtils.getUserClass(beanClass));
}
}
测试类
@SpringBootTest
public class CustomProcessorTest {
@Autowired
private ApplicationContext applicationContext;
@Test
void test(){
TestBean testBean = applicationContext.getBean(TestBean.class);
System.out.println(testBean);
}
/**
* 创建 TestBean 和 CustomInstantiationAwareBeanPostProcessor 这2个 bean
*/
@TestConfiguration
static class TestConfig{
@Bean
public TestBean getTestBean(){
TestBean testBean = new TestBean();
testBean.setField("1");
return testBean;
}
@Bean
public CustomInstantiationAwareBeanPostProcessor customInstantiationAwareBeanPostProcessor(){
return new CustomInstantiationAwareBeanPostProcessor();
}
}
}
执行结果
调用 postProcessBeforeInstantiation 方法
创建 TestBean 对象
设置 field 属性
调用 postProcessAfterInstantiation 方法
调用 postProcessProperties 方法
调用 postProcessBeforeInitialization 方法
调用初始化方法
调用 postProcessAfterInitialization 方法
TestBean{field=1}
分析方法
1. postProcessBeforeInstantiation()
postProcessBeforeInstantiation() 方法是在 Bean 创建之前调用的,该方法允许我们返回 Bean 的其他子类(我们也可以用 cglib 返回一个代理对象)。
这个方法在 InstantiationAwareBeanPostProcessor 接口的默认实现是返回 null。
结论
如果 postProcessBeforeInstantiation() 返回的不是 null ,那么 Spring 只会在 Bean 创建的时候,
只调用 postProcessBeforeInstantiation() 和 postProcessAfterInitialization() 方法。
验证
修改 CustomInstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation() 方法:
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (isMatchClass(beanClass)) {
System.out.println("调用 postProcessBeforeInstantiation 方法");
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanClass);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
System.out.println("目标方法执行前:" + method);
Object object = proxy.invokeSuper(obj, args);
System.out.println("目标方法执行后:" + method);
return object;
});
return enhancer.create();
}
return null;
}
执行结果:
调用 postProcessBeforeInstantiation 方法
创建 TestBean 对象
调用 postProcessAfterInitialization 方法
目标方法执行前:public java.lang.String TestBean.toString()
目标方法执行后:public java.lang.String TestBean.toString()
TestBean{field=null}
从执行结果中看,Spring 容器只执行了 postProcessBeforeInstantiation() 和 postProcessAfterInitialization() 方法,CustomInstantiationAwareBeanPostProcessor 其余的方法均不执行。
也没有执行 TestBean 的 setField() 和 afterPropertiesSet() 方法。
原因
从 Spring 创建 Bean 的过程中入手, Spring 在创建 Bean 时,会调用 AbstractAutowireCapableBeanFactory 的 createBean() 方法:
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
// 省略上面的方法
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
// 省略下面的方法
}
从 createBean() 的代码片段中,它先去调用 resolveBeforeInstantiation() 方法来尝试获取代理类,如果获取到了,就直接返回该代理类。
否则就去调用 doCreateBean() 方法,以创建 bean 的实例,并且返回。
resolveBeforeInstantiation() 方法以及调用到的关联方法:
@Nullable
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) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 这里会遍历每一个 InstantiationAwareBeanPostProcessor 的子类,所以 InstantiationAwareBeanPostProcessor 的子类顺序很重要
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
// 如果返回的不为 null ,后面的所有 InstantiationAwareBeanPostProcessor 的子类就跳过执行了
if (result != null) {
return result;
}
}
return null;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 这里会遍历每一个 BeanPostProcessor 的子类,所以 BeanPostProcessor 的子类顺序很重要
Object current = processor.postProcessAfterInitialization(result, beanName);
// 如果返回的为 null ,后面的所有 BeanPostProcessor 的子类就跳过执行了
if (current == null) {
return result;
}
result = current;
}
return result;
}
从 resolveBeforeInstantiation() 方法的代码片段中,它的逻辑基本是这样:
- 遍历所有的 InstantiationAwareBeanPostProcessor 实现类,调用其 postProcessBeforeInstantiation() 方法。
- 如果 postProcessBeforeInstantiation() 方法返回值,那么就表示找到了代理类,那么就会结束遍历
- 如果步骤2没有找到代理类,那么 resolveBeforeInstantiation() 方法就基本执行结束,返回 null 值。
- 如果步骤2找到了代理类,就会遍历所有 BeanPostProcessor 的实现类,调用其 postProcessAfterInitialization() 方法。
- 如果 postProcessAfterInitialization() 方法返回的是 null , 那么就返回上一次遍历得到的结果,或者是代理类本身。
2. postProcessAfterInstantiation()
postProcessAfterInstantiation() 方法的返回值会影响 postProcessProperties() 是否会执行:
- false :不会执行
- true :执行
原因
上面已经提及了 Spring 创建 Bean 是会调用 createBean() 方法,其中如果 postProcessBeforeInstantiation() 返回的值为 null 的话,就会执行 doCreateBean() 方法。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
// 忽略上面代码
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
// 忽略下面代码
}
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 忽略上面代码
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 遍历所有 InstantiationAwareBeanPostProcessor ,并调用其 postProcessAfterInstantiation() 方法,如果返回 false ,就不会执行后续步骤了。
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
// 忽略中间部分代码
if (hasInstantiationAwareBeanPostProcessors()) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 遍历所有 InstantiationAwareBeanPostProcessor ,并调用其 postProcessProperties() 方法,如果存在返回的值为 null ,就不会执行后续步骤了
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
pvs = pvsToUse;
}
}
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// 根据调用所有 InstantiationAwareBeanPostProcessor 的 postProcessProperties() 方法所得到的值,来修改这个 bean 的属性
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
从上面的代码片段中,doCreateBean() 方法会调用 populateBean() 方法,其中 populateBean() 方法它的主要逻辑是:
- 遍历所有 InstantiationAwareBeanPostProcessor ,调用 postProcessAfterInstantiation() 方法,如果返回值为 false 了,就不会执行后续步骤了
- 遍历所有 InstantiationAwareBeanPostProcessor ,调用 postProcessProperties() 方法,如果返回值为 null ,就不会执行后续的其他步骤了
- 如果 pvs 的值不为空,那么就去调用 applyPropertyValues() 方法来设置 bean 的属性
3. postProcessProperties()
postProcessProperties() 方法返回的 PropertyValues 会影响 bean 属性的设置。
结论
如果 PropertyValues 为 null ,PropertyValues 里面没有数据,就不会对 bean 的属性做任何修改。
否则,就会修改 Bean 的属性值。
验证
修改 CustomInstantiationAwareBeanPostProcessor 类的 postProcessProperties() 方法逻辑:
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (isMatchClass(bean.getClass())) {
System.out.println("调用 postProcessProperties 方法");
MutablePropertyValues mpvs = (MutablePropertyValues) pvs;
// 这里修改 TestBean 的 field 字段值为 "update value"
mpvs.add("field","update value");
}
return pvs;
}
输出结果:
调用 postProcessBeforeInstantiation 方法
创建 TestBean 对象
设置 field 属性
调用 postProcessAfterInstantiation 方法
调用 postProcessProperties 方法
设置 field 属性
调用 postProcessBeforeInitialization 方法
调用初始化方法
调用 postProcessAfterInitialization 方法
TestBean{field=update value}
4. postProcessBeforeInitialization() 和 postProcessAfterInitialization()
postProcessBeforeInitialization() 和 postProcessAfterInitialization() 这2个方法是在 Bean 的属性设置完之后执行的,可以通过这2个方法来完成对 Bean 的属性进行修改。
当 Spring 在 AbstractAutowireCapableBeanFactory 的 doCreateBean() 方法中调用完了 populateBean() 的方法后,就会调用 initializeBean() 方法。
故 initializeBean() 方法是 Spring 调用 postProcessBeforeInitialization() 和 postProcessAfterInitialization() 的主要逻辑:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 遍历所有 BeanPostProcessor 的子类,并调用 postProcessBeforeInitialization() 的方法
// 如果 postProcessBeforeInitialization() 返回 null ,则返回上一个 BeanPostProcessor 子类返回的对象,
// 或者是 bean 对象本身(如果调用第一个 BeanPostProcessor 子类就返回 null 的话)
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用 bean 指定的 init 方法,或者是实现 InitializingBean 的 afterPropertiesSet() 方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 遍历所有 BeanPostProcessor 的子类,并调用 postProcessAfterInitialization() 的方法
// 如果 postProcessAfterInitialization() 返回 null ,则返回上一个 BeanPostProcessor 子类返回的对象,
// 或者是 bean 对象本身(如果调用第一个 BeanPostProcessor 子类就返回 null 的话)
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。