概念
谈论到实例化处理器和初始化处理器,我们要明确一个实例化和初始化概念,大牛们可以忽略此处说明。
- 实例化:指创建类实例(对象)的过程。比如使用构造方法new对象,为对象在内存中分配空间。(要创建对象,但是并未生成对象)
- 初始化:指为类中各个类成员(被static修饰的成员变量)赋初始值的过程,是类生命周期中的一个阶段。简单理解为对象中的属性赋值的过程。(对象已经生成,为其属性赋值)
源码
从源码解读实例化处理器和初始化处理器。
- InstantiationAwareBeanPostProcessor 该接口继承自BeanPostProcessor接口,并自定义如图方法。
- postProcessBeforeInstantiation 实例化前置处理 (对象未生成)
- postProcessAfterInstantiation 实例化后置处理 (对象已经生成)
- postProcessPropertyValues 修改属性值。(对象已经生成)
- BeanPostProcessor
- postProcessBeforeInitialization初始化前置处理 (对象已经生成)
- postProcessAfterInitialization初始化后置处理 (对象已经生成)
触发处理器时机
从Bean的生命周期流程中可知,实例化和初始化处理器作用时机主要在初始化Bean前后。 主要在类AbstractAutowireCapableBeanFactory中
代码语言:javascript复制protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" beanName "'");
}
RootBeanDefinition mbdToUse = mbd;
//根据设置的class属性或者根据className来解析class:调用AbstractBeanFactory类
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
//验证以及准备覆盖的方法即Override方法
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//返回代理来代替真正的实例:--------------应用实例化前的前置处理器
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//短路操作,返回bean
if (bean != null) {
//返回bean的代理对象
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//---------------创建单例bean对象:核心方法doCreateBean(常规bean的创建过程)
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" beanName "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
- 触发postProcessBeforeInstantiation时机 postProcessBeforeInstantiation调用时机: BeanDefinition创建Bean的开端是在createBean()方法也就是流水线的开始处。 注意是否返回bean的代理对象,如果返回Bean的代理对象,则直接return代理对象;即resolveBeforeInstantiation()方法,源代码如下
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//是否实现前置处理器接口
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//调用InstantiationAwareBeanPostProcessor:实例化前置处理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//调用初始化后置处理器,doCreateBean流程结束
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
解释说明:
- 首先,判断是否存在InstantiationAwareBeanPostProcessor接口的处理器
- 如存在,则调用的是InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()实例化前置处理方法,也就是在Bean对象没有生成之前执行(实例化过程中)。(注意:这里所说的是Bean未生成指的是Bean没有走spring定义创建Bean的流程,也就是doCreateBean()方法。)
- 如果postProcessBeforeInstantiation()返回的对象不为空, 意味着Bean对象已经存在,表明对象已经初始化完成。然后调用postProcessAfterInitialization()初始化后置处理器,完成对Bean对象的操作. 如果postProcessBeforeInstantiation()返回值为空,则进入上层调用者createBean()方法,继续调用doCreateBean()方法,完成对象实例化(创建对象),以及对象初始化.
- postProcessAfterInstantiation调用时机 上面createBean()方法中标识若resolveBeforeInstantiation()方法没有返回bean,则调用doCreateBean()方法,进入创建bean流程中; 下面我们开始分析doCreateBean()的部分代码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
...//省略部分源码
// Initialize the bean instance.
//------------------------完成实例化bean创建,下面开始进行------bean初始化操作-------------
Object exposedObject = bean;
try {
//----****属性填充操作:其中可能会存在依赖其他bean属性,则会递归初始化依赖bean****
populateBean(beanName, mbd, instanceWrapper);
//--- ****初始化指定的bean实例*****,回调init()方法和执行处理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
...//省略后面代码
}
跟踪populateBean()方法的源码实现,便可以发现postProcessAfterInstantiation() 与postProcessPropertyValues()依次被执行。该方法仍然处于实例化过程。
代码语言:javascript复制...省略部分源码
//是否实现InstantiationAwareBeanPostProcessor接口,以及bean是否依赖检查
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
//处理实现了InstantiationAwareBeanPostProcessor
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//一次调用实现的InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
- postProcessBeforeInitialization、 postProcessAfterInitialization 初始化前后处理器,从initializeBean()方法中依次被调用执行
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//如果bean是BeanNameAware,BeanClassLoaderAware或者BeanFactoryAware其中某一个的实现类就需要进行处理
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//bean生命周期之一:如果实现了BeanPostProcessor接口,则会在此调用实现类中的beanPostProcessorsBeforeInitialization()方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//bean生命周期之一:如果实现InitializingBean接口,则会在此调用实现类中的afterPropertiesSet()方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//bean生命周期之一:如果实现了BeanPostProcessor接口,则会在此调用实现类中的beanPostProcessorAfterInitialization()方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
总结
- BeanPostProcessor定义的方法是在对象初始化过程中做处理,分别在resolveBeforeInstantiation()触发后置处理器,或者在initializeBean依次调用前后处理器。
- InstantiationAwareBeanPostProcessor定义的方法是在对象实例化过程中做处理,即分别在resolveBeforeInstantiation()、populateBean()触发前置处理器,后置处理器。 从上面分析可知: 实例化—>初始化过程中会形成两条路径。
- postProcessBeforeInstantiation()–自定义对象–>postProcessAfterInitialization();
- postProcessBeforeInstantiation() -->postProcessAfterInstantiation–>postProcessBeforeInitialization()–>postProcessAfterInitialization() postProcessBeforeInstantiation一定执行, postProcessAfterInitialization一定执行.
参考资料:https://juejin.im/post/5da995d25188256a49204d7b