Spring读源码系列05----bean的加载---下
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring读源码系列05----bean的加载---下相关的知识,希望对你有一定的参考价值。
Spring读源码系列05----bean的加载---下
阅读本系列之前,建议先从本专栏的两个不同视角学习spring的系列作为入门学习点(这两个系列会持续更新),先大体理解spring的架构设计与精髓,然后再来阅读本系列,深入源码分析,而不再纸上谈兵。
从整体来学spring系列文章:
Spring复杂的BeanFactory继承体系该如何理解? ----上
Spring复杂的BeanFactory继承体系该如何理解? ----中
Spring复杂的BeanFactory继承体系该如何理解?—中下
Spring复杂的BeanFactory继承体系该如何理解?—下
该系列持续更新中…
独特视角学习spring系列文章:
该系列持续更新中…
本系列文章:
Spring读源码系列03----自定义标签解析(待续中)
番外篇:
Spring读源码系列番外篇—01–PropertyValue相关类
初始化Bean
先回顾一下初始化方法的调用时机:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton())
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
if (instanceWrapper == null)
instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class)
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock)
if (!mbd.postProcessed)
try
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
catch (Throwable ex)
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
mbd.postProcessed = true;
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure)
if (logger.isTraceEnabled())
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// Initialize the bean instance.
Object exposedObject = bean;
try
populateBean(beanName, mbd, instanceWrapper);
//这个就是我们要讲的方法!!!
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);
if (earlySingletonExposure)
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null)
if (exposedObject == bean)
exposedObject = earlySingletonReference;
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName))
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans)
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean))
actualDependentBeans.add(dependentBean);
if (!actualDependentBeans.isEmpty())
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
// Register bean as disposable.
try
registerDisposableBeanIfNecessary(beanName, bean, mbd);
catch (BeanDefinitionValidationException ex)
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
return exposedObject;
AbstractAutowireCapableBeanFactory#initializeBean—初始化Bean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
//1.触发aware相关接口的注入
if (System.getSecurityManager() != null)
AccessController.doPrivileged((PrivilegedAction<Object>) () ->
invokeAwareMethods(beanName, bean);
return null;
, getAccessControlContext());
else
invokeAwareMethods(beanName, bean);
//2.后置处理器的应用
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic())
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//3.调用init-method反复
try
invokeInitMethods(beanName, wrappedBean, mbd);
catch (Throwable ex)
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
//4.后置处理器的应用
if (mbd == null || !mbd.isSynthetic())
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
AbstractAutowireCapableBeanFactory#invokeAwareMethods—激活aware方法
private void invokeAwareMethods(String beanName, Object bean)
if (bean instanceof Aware)
if (bean instanceof BeanNameAware)
((BeanNameAware) bean).setBeanName(beanName);
if (bean instanceof BeanClassLoaderAware)
ClassLoader bcl = getBeanClassLoader();
if (bcl != null)
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
if (bean instanceof BeanFactoryAware)
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
说实话,这段源码实在没啥好讲的,aware接口本身就比较常用,大家应该也能猜到是这种方式实现的,如果你有自定义的需求,那么可以通过增加一个适当的后置处理器来进行实现
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors())
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null)
return result;
result = current;
return result;
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@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;
激活自定义的init方法
/**
* Give a bean a chance to react now all its properties are set,
* and a chance to know about its owning bean factory (this object).
* This means checking whether the bean implements InitializingBean or defines
* a custom init method, and invoking the necessary callback(s) if it does.
*/
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable
//如果是isInitializingBean ,会调用其重新的afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet")))
if (logger.isTraceEnabled())
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
if (System.getSecurityManager() != null)
try
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
((InitializingBean) bean).afterPropertiesSet();
return null;
, getAccessControlContext());
catch (PrivilegedActionException pae)
throw pae.getException();
else
((InitializingBean) bean).afterPropertiesSet();
if (mbd != null && bean.getClass() != NullBean.class)
//调用自定义初始化方法
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName))
invokeCustomInitMethod(beanName, bean, mbd);
注册DisposableBean
先回顾一下销毁方法处理逻辑在哪里被调用的:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton())
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
if (instanceWrapper == null)
instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class)
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock)
if (!mbd.postProcessed)
try
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
catch (Throwable ex)
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
mbd.postProcessed = true;
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure)
if (logger.isTraceEnabled())
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// Initialize the bean instance.
Object exposedObject = bean;
try
populateBean(beanName, mbd, instanceWrapper);
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);
if (earlySingletonExposure)
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null)
if (exposedObject == bean)
exposedObject = earlySingletonReference;
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName))
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans =以上是关于Spring读源码系列05----bean的加载---下的主要内容,如果未能解决你的问题,请参考以下文章