Spring版本
5.2.5.RELEASE
参考
源码解析
在上一篇《Spring源码解析-获取单例bean》中,在doGetBean
的最后,调用了getSingleton
方法,并且将beanName
和一个返回createBean
方法的匿名方法作为参数传入:
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
// 在早期的创建过程中,可能为了解决循环引用问题,导致beanName加入了singleton缓存中,此时需要移除该缓存
destroySingleton(beanName);
throw ex;
}
});
那么我们先看看getSingleton
方法
1. DefaultSingletonBeanRegistry#getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 从缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 写入singletonsCurrentlyInCreation
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 这里的getObject方法实际上调用的是singletonFactory匿名函数的createBean方法
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
// createBean方法有可能抛出ImplicitlyAppearedSingletonException异常
// 该异常是IllegalStateException的子类,当这种异常出现的时候,此时bean可能已经被隐含地(implicitly)实例化
// 所以这一步需要再从singletonObjects这个已实例化的集合汇总获取一次实例化对象
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 从singletonsCurrentlyInCreation移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 针对singleton做一些缓存方面的处理,如加入<beanName,bean>的缓存、从早起引用map中移除等
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
首先从缓存中获取bean实例,如果存在,直接返回,否则进行创建的流程。
这里面入参singletonFactory
是一个函数式接口参数:
@FunctionalInterface
public interface ObjectFactory<T> {
/**
* Return an instance (possibly shared or independent)
* of the object managed by this factory.
* @return the resulting instance
* @throws BeansException in case of creation errors
*/
T getObject() throws BeansException;
}
因此,singletonFactory.getObject()
实际上就是调用createBean
方法
2. AbstractAutowireCapableBeanFactory#createBean
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;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 确认到了这一步bean类型已经被解析,以防动态解析class的情况下,mdb的beanClass属性为空
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 处理look-up method和replace method
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 看英文注释这里是给BeanPostProcessors一个机会返回一个代理对象而不是bean实例
// 但是resolveBeforeInstantiation内部代码感觉又没有进去执行具体逻辑,具体后面解析
// TODO
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 {
// 真正创建bean实例
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);
}
}
1、通过resolveBeanClass
解析mdb的beanClass
属性
2、处理了lookup-method和replace-method俩种注入,关于这俩种注入方法,可以戳:14--Spring lookup-method注入和replace-method注入(二)
3、通过resolveBeforeInstantiation
给BeanPostProcessor
一个机会返回代理对象
4、最后调用了doCreateBean
进行创建
2.1 AbstractAutowireCapableBeanFactory#resolveBeanClass
@Nullable
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
// 如果mbd已经解析出beanClass,直接返回
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
// 否则,进行解析逻辑
return doResolveBeanClass(mbd, typesToMatch);
}
}
catch (PrivilegedActionException pae) {
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
-
mbd
已经有beanClass
,那么直接返回 - 否则,调用
doResolveBeanClass
进行解析
2.2 AbstractAutowireCapableBeanFactory#doResolveBeanClass
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
// 获取文本类型的className,通过className和classLoader来获取beanClass
String className = mbd.getBeanClassName();
if (className != null) {
// 貌似是解析SPEL表达式的,这块没看懂
Object evaluated = evaluateBeanDefinitionString(className, mbd);
// 如果俩者不相同,说明使用了SPEL表达式
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (dynamicLoader != null) {
try {
// dynamicLoader不为空,通过dynamicLoader
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
// 如果dynamicLoader为空,通过forName进行加载
return ClassUtils.forName(className, dynamicLoader);
}
}
// Resolve regularly, caching the result in the BeanDefinition...
// 如果className为空,进行常规加载(该方法内部其实也是通过ClassUtils.forName(className, classLoader))
return mbd.resolveBeanClass(beanClassLoader);
}
获取string类型的className,加载获得对应的class
1.3 AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
// 单例模型,则从未完成的 FactoryBean 缓存中删除
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final 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.
// 这里是早期引用的逻辑,用于解决单例模式的循环引用,需要满足一下三个条件:
// 1、单例模式
// 2、开启早期引用
// 3、beanName正在创建中(A依赖B,B依赖A,先创建A,发现依赖B,去创建B,结果发现依赖A,又再去创建A)
// 第三点解释如下:
// 情景:A依赖B,B依赖A
// 过程:
// 1、创建A,走到这一步,A没有处于创建中,earlySingletonExposure此时为false,继续往下走,将A正在创建中写入singletonsCurrentlyInCreation
// 2、发现依赖B,去创建B
// 3、创建B,走到这一步,B也没有处于创建中,同步骤一继续往下走
// 4、发现依赖A,去创建A
// 5、创建A,此时,A已经处于singletonsCurrentlyInCreation了,此时满足条件,进入if分支
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");
}
// 解决循环引用,提前将bean实例写入singletonFactories、earlySingletonObjects和registeredSingletons
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充属性
populateBean(beanName, mbd, instanceWrapper);
// 实例化bean
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) {
// addSingletonFactory中已经将bean加入earlySingletonObjects中,这里从中获取
Object earlySingletonReference = getSingleton(beanName, false);
// 只有循环依赖的情况下if分支的条件才会成立
if (earlySingletonReference != null) {
// exposedObject初始赋值便是bean,那么说明其没有被initializeBean方法改变
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
// allowRawInjectionDespiteWrapping:是否在循环依赖的情况下重新整理成原生bean
// 个人理解是为了解决循环依赖问题,之前使用了早期引用,
// 而一旦allowRawInjectionDespiteWrapping为true,那么就将该早期引用替换成原声bean
// 不过这里的allowRawInjectionDespiteWrapping是false的情况下else if分支成立
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// alreadyCreated 不包含dependentBean的情况下if分支成立
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
// 如果alreadyCreated包含任何一个dependentBean,那么这里if分支成立,此时抛出异常
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 注册bean销毁逻辑
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
1、使用createBeanInstance
创建一个instanceWrapper
,详见《Spring源码解析(九)-创建bean实例》
2、应用后置BeanPostProcessor
3、解决单例模式下循环引用的问题
4、通过populateBean
填充属性,详见《Spring源码解析(十)-填充bean属性》
5、通过initializeBean
应用init-method
方法,详见《Spring源码解析(十一)-初始化bean》
6、实例化depends on
对应的bean
7、调用registerDisposableBeanIfNecessary
注册bean的销毁逻辑,详见《Spring源码解析(十二)-注册bean销毁逻辑》
8、返回创建完毕的bean实例
总结
创建单例bean的核心都在doCreateBean
方法中,该方法分别实现了创建bean实例、应用BeanPostProcessors
、解决循环引用问题、填充bean属性、应用init-method
方法、实例化depends on
对应的bean和注册bean销毁逻辑等功能,内容较多,需要逐个慢慢解析击破
网友评论