Spring - InstantiationAwareBeanPostProcessor 扩展接口
Posted 小小工匠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring - InstantiationAwareBeanPostProcessor 扩展接口相关的知识,希望对你有一定的参考价值。
文章目录
- Pre
- org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
- InstantiationAwareBeanPostProcessor 注册过程源码分析
- 使用场景 : 创建代理类
Pre
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
注意下: Initialization 表示 实例化 (意思是对象还未生成) 。 Instantiation 表示 初始化 (意思是对象已经生成) 。
接口继承了BeanPostProcess
接口 , 从方法上我们也可以看出 InstantiationAwareBeanPostProcessor
做了一些扩展 。
BeanPostProcess
接口只在bean的初始化阶段进行扩展(注入spring上下文前后),而InstantiationAwareBeanPostProcessor
接口在此基础上增加了3个方法,使得扩展接口可以在实例化阶段和属性注入阶段
该类主要的扩展点有以下5个方法,主要在bean生命周期的两大阶段:实例化阶段 和初始化阶段 ,
(1)实例化: 实例化的过程是一个创建Bean的过程,即调用Bean构造函数,单例的Bean入单例池中
(2)初始化: 初始化的过程是一个赋值的过程,即调用Bean的setter方法,设置Bean属性
InstantiationAwareBeanPostProcessor
作用于过程(1)实例化前后; BeanPostProcessor
用于过程(2)初始化前后
按调用顺序,我们来看一下
postProcessBeforeInstantiation
:实例化bean之前,相当于new这个bean之前postProcessAfterInstantiation
:实例化bean之后,相当于new这个bean之后postProcessPropertyValues:
bean已经实例化完成,在属性注入时阶段触发,@Autowired,@Resource
等注解原理基于此方法实现postProcessBeforeInitialization
:初始化bean之前,相当于把bean注入spring上下文之前postProcessAfterInitialization
:初始化bean之后,相当于把bean注入spring上下文之后
InstantiationAwareBeanPostProcessor 注册过程源码分析
我们还是从
org.springframework.context.support.AbstractApplicationContext#refresh
开始看 ,主要是下面两个方法
.......
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
.......
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
看下调用栈
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors()
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
org.springframework.beans.factory.support.AbstractBeanFactory#getBean
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
createBean
跟进去
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null)
return bean;
//省略....
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
通过上面的代码,我们可以看到在执行doCreateBean
之前有resolveBeforelnstantiation
方法; 看注释
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
resolveBeforelnstantiation
判断执行InstantiationAwareBeanPostProcessor.postProcessBeforelInstantiationg
接口方法实现;doCreateBean
创建bean方法;
postProcessBeforeInstantiation的执行时机源码解析
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors()
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
org.springframework.beans.factory.support.AbstractBeanFactory#getBean
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
重点看 resolveBeforeInstantiation
/**
* Apply before-instantiation post-processors, resolving whether there is a
* before-instantiation shortcut for the specified bean.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return the shortcut-determined bean instance, or @code null if none
*/
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)
Object bean = null;
//如果beforeInstantiationResolved还没有设置或者是false(说明还没有需要在实例化前执行的操作)
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved))
// Make sure bean class is actually resolved at this point.
// 判断是否有注册过InstantiationAwareBeanPostProcessor类型的bean
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;
继续 applyBeanPostProcessorsBeforeInstantiation
/**
* Apply InstantiationAwareBeanPostProcessors to the specified bean definition
* (by class and name), invoking their @code postProcessBeforeInstantiation methods.
* <p>Any returned object will be used as the bean instead of actually instantiating
* the target bean. A @code null return value from the post-processor will
* result in the target bean being instantiated.
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return the bean object to use instead of a default instance of the target bean, or @code null
* @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
*/
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
// 循环处理
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware)
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
//只要有一个result不为null;后面的所有 后置处理器的方法就不执行了,直接返回(所以执行顺序很重要)
if (result != null)
return result;
return null;
当然了也有 postProcessAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors())
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null)
return result;
result = current;
return result;
使用场景 : 创建代理类
package com.artisan.bootspringextend.testextends;
import com.artisan.bootspringextend.service.ArtisanServiceImpl;
import com.artisan.bootspringextend.service.ClassA;
import com.artisan.bootspringextend.service.ClassAInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.context.annotation.Configuration;
/**
* @author 小工匠
* @version 1.0
* @description:
* @date 2022/11/28 0:33
* @mark: show me the code , change the world
*/
@Slf4j
@Configuration
public class ExtendInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor
private static final String VALUE = "classA";
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
if (VALUE.equals(beanName))
log.info("4 beanName -----> postProcessBeforeInitialization", beanName);
return bean;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
if (VALUE.equals(beanName))
log.info("5 beanName -----> postProcessAfterInitialization", beanName);
return bean;
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException
if (beanClass == ClassA.class)
log.info("1 beanName -----> postProcessBeforeInstantiation", beanName);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanClass);
enhancer.setCallback(new ClassAInterceptor());
ClassA classA = (ClassA) enhancer.create();
log.info("proxy created ---->", classA.toString());
return classA;
return null;
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException
if (VALUE.equals(beanName))
log.info("2 beanName -----> postProcessAfterInstantiation", beanName);
return false;
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException
if (VALUE.equals(beanName))
log.info("3 beanName -----> postProcessProperties", beanName);
return pvs;
我们可以看到 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
生成了代理类后,直接执行了 初始化后的动作 BeanPostProcessor#postProcessAfterInitialization
。
以上是关于Spring - InstantiationAwareBeanPostProcessor 扩展接口的主要内容,如果未能解决你的问题,请参考以下文章
Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC
学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签
Spring框架--Spring事务管理和Spring事务传播行为