相关文章
Spring IOC系列学习笔记一:前置刷新
Spring IOC系列学习笔记二:obtainFreshBeanFactory方法
Spring IOC系列学习笔记三:parseDefaultElement详解
Spring IOC系列学习笔记四:parseCustomElement解析
Spring IOC系列学习笔记五:context:component-scan 节点解析
Spring IOC系列学习笔记六:invokeBeanFactoryPostProcessors解析
Spring IOC系列学习笔记七:registerBeanPostProcessors
Spring IOC系列学习笔记八:finishBeanFactoryInitialization
Spring IOC系列学习笔记九:getBean方法
Spring IOC系列学习笔记十:createBean方法(上)
Spring IOC系列学习笔记十一:createBean方法(下)
Spring IOC系列学习笔记十二:@Autowire注解
文章目录
- 相关文章
- 前言
- 代码块一:getBean
- 代码块二:getObjectForBeanInstance
- 代码块三:getObjectFromFactoryBean
- 代码块四:doGetObjectFromFactoryBean
- 代码块五:postProcessObjectFromFactoryBean
- 代码块六:markBeanAsCreated
- 代码块七:isDependent
- 代码块八:registerDependentBean
- 代码块九:getSingleton
- 代码块十:beforeSingletonCreation&afterSingletonCreation
- 代码块十一:addSingleton
- 代码块十二:beforePrototypeCreation、afterPrototypeCreation
- 总结
前言
前面讲解了finishBeanFactoryInitialization方法,接着进入getBean方法的解析。
代码块一:getBean
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
1、解析beanName,主要是去掉&前缀
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
2、从缓存中获取bean实例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
3、如果缓存中存在并且args参数为空,则直接获取beanName的实例对象
(主要是解析FactoryBean,如果不是该类型则直接返回)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
判断scope为prototype的循环依赖校验,就是如果A已经在正在创建的缓存,而现在我们在当前线程中还要创建该实例,则出现循环依赖。
Spring中对多例的循环依赖没有解决所以直接抛出异常。
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
4.1、获取parentBeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
4.2、parentBeanFactory不为空&&缓存中不存在beanName,尝试从父容器创建bean实例
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
4.3、规范beanName
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
5、如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
移除了mergedBeanDefinitions中的beanName,后续创建一个最新的
markBeanAsCreated(beanName);
}
try {
6.1、创建一个新的
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
6.2、拿到该实例以来的bean集合
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
6.3、判断dep是否依赖beanName,检查循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
6.4、将dep和beanName注册到依赖缓存中,引进了两个缓存(容易搞混淆)
registerDependentBean(dep, beanName);
6.5、获取依赖bean的实例
getBean(dep);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
7、如果是单例的创建一个单例对象(lambda表达式重写了ObjectFactory的getObject方法)
sharedInstance = getSingleton(beanName, () -> {
try {
7.1、创建bean实例对象
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.
destroySingleton(beanName);
throw ex;
}
});
7.2、返回beanName对应的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
8.1、scope是prototype的bean创建
Object prototypeInstance = null;
try {
8.2、创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
8.3、创建bean实例对象
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
8.4、创建实例后的操作(将beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
8.5、返回beanName对应的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
9.1、其他scope的bean创建,可能是request之类的
9.2、根据scopeName,从缓存拿到scope实例
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
9.3、其他scope的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
10、检查所需类型是否与实际的bean对象的类型匹配
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
10.1、类型不对,则尝试转换bean类型
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
2、从缓存中获取bean实例建见finishBeanFactoryInitialization中的代码块七
3、返回beanName对应的实例对象见代码块二
5、如果不是仅仅做类型检测,而是创建bean实例见代码块六
6.3、判断dep是否依赖beanName,检查循环依赖代码块isDependent见代码块七
6.4、将dep和beanName注册到依赖缓存中,引进了两个缓存(容易搞混淆)代码块八
7、如果是单例的创建一个单例对象代码块九
8.2和8.4、创建实例前的操作和创建实例后的操作代码块十二
代码块二:getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
1、name包含前缀& 并且beanInstance不是FactoryBean类型直接抛出异常
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
2.1、beanInstance不是FactoryBean直接返回
2.2、beanInstance是FactoryBean并且name包含前缀& 表示要的就是FactoryBean的实例则直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
3、到这儿表示 beanInstance是FactoryBean但是name前缀不包含&,则要用FactoryBean来创建bean的实例
Object object = null;
if (mbd == null) {
3.1、从factoryBeanObjectCache缓存中获取bean的实例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
3.2、直接转换成FactoryBean
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
3.3、mbd为null并且缓存中存在beanName,则获取该bean的MergedLocalBean
mbd = getMergedLocalBeanDefinition(beanName);
}
3.4、判断是不是合成的
boolean synthetic = (mbd != null && mbd.isSynthetic());
3.5、从FactoryBean中获取实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
3.5、从FactoryBean中获取实例见代码块三
代码块三:getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
1、factory是单例的&&beanName存在缓存中
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
2.1、从factoryBeanObjectCache缓存中获取该beanName的实例
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
2.2、真正的创建方法 带do开头的
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
2.3、再从从缓存中获取
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
2.4、如果获取到了则替换,用从缓存中获取的
object = alreadyThere;
}
else {
if (shouldPostProcess) {
try {
2.5、FactoryBean的后置处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
2.6、放到缓存当中
this.factoryBeanObjectCache.put(beanName, object);
}
}
return object;
}
}
else {
3.1、调用FactoryBean的getObject方法获取对象实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
3.2、对bean实例进行后置处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
2.2、真正的创建方法 带do开头的见代码块四
3.2、对bean实例进行后置处理见代码块五
代码块四:doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
1、带权限验证执行getObject方法获取bean实例
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
factory.getObject(), acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
2、直接获取
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
代码块五:postProcessObjectFromFactoryBean
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessAfterInitialization方法
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 2.在bean初始化后,调用postProcessAfterInitialization方法
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
// 3.如果返回null,则不会调用后续的BeanPostProcessors
return result;
}
}
return result;
}
这儿执行的是AbstractAutowireCapableBeanFactory中的方法。我们回到代码块一进入5。
代码块六:markBeanAsCreated
protected void markBeanAsCreated(String beanName) {
1、alreadyCreated缓存中不包含beanName
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
2、从mergedBeanDefinitions移除了beanName的实例,后续重新创建一个新的
clearMergedBeanDefinition(beanName);
3、将beanName添加进已经创建或者正在创建的缓存中
this.alreadyCreated.add(beanName);
}
}
}
}
代码块七:isDependent
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
1、已经检查直接跳过
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
2、规范名称
String canonicalName = canonicalName(beanName);
3、获取依赖canonicalName的beanName集合
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
4、如果为空表示没有依赖beanName的直接返回
if (dependentBeans == null) {
return false;
}
5、dependentBeans包含了dependentBeanName,表示dependentBeanName依赖了beanName,出现循环依赖
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
6、循环检查,即检查依赖canonicalName的所有beanName是否存在被dependentBeanName依赖的(即隔层依赖)
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
这边引入了一个缓存 dependentBeanMap:beanName -> 所有依赖 beanName 对应的 bean 的 beanName 集合。内容比较简单,就是检查依赖 beanName 的集合中是否包含 dependentBeanName,隔层依赖也算。例如:A 依赖了 B,B 依赖了 C,则 A 也算依赖了 C。
代码块八:registerDependentBean
public void registerDependentBean(String beanName, String dependentBeanName) {
// A quick check for an existing entry upfront, avoiding synchronization...
1、规范beanName名称
String canonicalName = canonicalName(beanName);
2、获取依赖canonicalName的bean的集合
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
3、dependentBeans不为空&& dependentBeanName在缓存中表示已经存在依赖关系了不需要再次创建
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
return;
}
// No entry yet -> fully synchronized manipulation of the dependentBeans Set
4、如果依赖关系还没有注册,则将两者的关系注册到dependentBeanMap和dependenciesForBeanMap缓存
synchronized (this.dependentBeanMap) {
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<>(8);
5、存入缓存中,dependentBeans表示的是依赖key的bean是value集合
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<>(8);
6、dependenciesForBeanMap表示key依赖的bean是value集合
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
dependenciesForBean.add(canonicalName);
}
}
这两个缓存很容易搞混,举个简单例子:例如 B 依赖了 A,则 dependentBeanMap 缓存中应该存放一对映射:其中 key 为 A,value 为含有 B 的 Set;而 dependenciesForBeanMap 缓存中也应该存放一对映射:其中 key 为:B,value 为含有 A 的 Set。
代码块九:getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
1、从单例缓存中获取bean实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
2、如果当前bean处于销毁状态不允许创建抛出异常
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 + "'");
}
3、创建之前的操作,主要是将bean加入到singletonsCurrentlyInCreation缓存
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
4、创建了实例
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.
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;
}
5、后续操作,对应3主要是将bean从singletonsCurrentlyInCreation缓存中移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
6、如果是新的单例对象,将beanName和对应的bean实例添加到缓存中(singletonObjects、registeredSingletons)
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
3和5、创建前后的操作见代码块十
6、如果是新的单例对象,将beanName和对应的bean实例添加到缓存中(singletonObjects、registeredSingletons)见代码块十一
代码块十:beforeSingletonCreation&afterSingletonCreation
protected void beforeSingletonCreation(String beanName) {
// 先校验beanName是否为要在创建检查排除掉的(inCreationCheckExclusions缓存),如果不是,
// 则将beanName加入到正在创建bean的缓存中(Set),如果beanName已经存在于该缓存,会返回false抛出异常(这种情况出现在构造器的循环依赖)
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
protected void afterSingletonCreation(String beanName) {
// 先校验beanName是否为要在创建检查排除掉的(inCreationCheckExclusions缓存),如果不是,
// 则将beanName从正在创建bean的缓存中(Set)移除,如果beanName不存在于该缓存,会返回false抛出异常
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
代码块十一:addSingleton
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 1.添加到单例对象缓存
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
// 2.将单例工厂缓存移除(已经不需要)
this.singletonFactories.remove(beanName);
// 3.将早期单例对象缓存移除(已经不需要)
this.earlySingletonObjects.remove(beanName);
// 4.添加到已经注册的单例对象缓存
this.registeredSingletons.add(beanName);
}
}
代码块十二:beforePrototypeCreation、afterPrototypeCreation
protected void beforePrototypeCreation(String beanName) {
// 1.拿到当前线程中正在创建的prototype的bean的beanName集合
Object curVal = this.prototypesCurrentlyInCreation.get();
// 2.如果为空,则将ThreadLocal设置成当前的beanName
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
}
// 3.如果不为空,并且是String类型,则代表目前只有一个beanName,将之前和当前的一起封装成Set<String>,设置到ThreadLocal中
else if (curVal instanceof String) {
Set<String> beanNameSet = new HashSet<String>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
// 4.如果不为空,并且不是String,则必然是Set<String>类型,将当前的beanName加到Set中去
else {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.add(beanName);
}
}
protected void afterPrototypeCreation(String beanName) {
// 1.拿到当前线程中正在创建的prototype的bean的beanName集合
Object curVal = this.prototypesCurrentlyInCreation.get();
// 2.如果是String类型,则代表目前只有一个beanName,则直接移除
if (curVal instanceof String) {
this.prototypesCurrentlyInCreation.remove();
}
else if (curVal instanceof Set) {
// 3.如果是Set类型,则从Set从移除beanName
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.remove(beanName);
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.remove();
}
}
}
主要是在进行 bean 实例的创建前,将 beanName 添加到 prototypesCurrentlyInCreation 缓存;bean 实例创建后,将 beanName 从 prototypesCurrentlyInCreation 缓存中移除。这边 prototypesCurrentlyInCreation 存放的类型为 Object,在只有一个 beanName 的时候,直接存该 beanName,也就是 String 类型;当有多个 beanName 时,转成 Set 来存放。
总结
本文介绍了获取 bean 实例的大部分内容,包括先从缓存中检查、 FactoryBean 的 bean 创建、实例化自己的依赖(depend-on 属性)、创建 bean 实例的前后一些标记等,在下篇文章中,将解析创建 bean 的内容。