文章目录
doGetBean源码:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 先将方法传入的name转换成容器真实的beanName // 之前可以通过三种形式获取beanName // 一个是原始的beanName,一个是加了&的,一个是别名 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); // 加果先前已经创建过单例Bean的实例,并且调用的getBean方法传入的参数为空,则执行理面的逻辑 // args之所以要求为空是因为如果有args,则需要做进一步赋值,因此无法直接返回 if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { // 如果Bean还在创建中,则说明是循环引用 if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } // 如果是普通bean,直接返回,如果是FactoryBean,则返回他的getObject bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. 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 if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. // 如果BeanDefinition为单例 if (mbd.isSingleton()) { // 这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象 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. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { 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 { 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. if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
之前讨论了doGetBean里面从缓存获取bean的代码,doGetBean方法接下来的else处理Bean的scope为prototype或者单例模式但是缓存中还不存在bean的情况:
Spring同样为scope为prototype的Bean设计了一个缓存列表
if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }
protected boolean isPrototypeCurrentlyInCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); return (curVal != null && (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName)))); }
相比单例的set,这里是ThreadLocal,只记录当前线程创建出来的scope为prototype的Bean,上面的if如果是true的话证明有循环依赖。
通过了循环依赖校验之后看容器是否存在父容器,如果存在且当前容器里没有包含此bean的BeanDefinition实例,尝试去从父类容器递归查询
为了防止之前的beanName已经被转换的不成样子,将&重新加上,再调用父类的doGetBean或者getBean方法,如果父类是AbstractBeanFactory,则调用doGetBean
如果当前容器里包含了此bean的BeanDefinition实例则继续执行
// typeCheckOnly 是用来判断调用 getBean() 是否仅仅是为了类型检查获取 bean,而不是为了创建Bean if (!typeCheckOnly) { // 如果不是仅仅做类型检查则是创建bean markBeanAsCreated(beanName); }
进入markBeanAsCreated方法里,
protected void markBeanAsCreated(String 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. // 将原先合并之后的RootBeanDefinition的需要重新合并的状态设置为true // 表示需要重新合并一遍,以防原数据的改动 clearMergedBeanDefinition(beanName); // 将已经创建好的或者正在创建的Bean的名称加到alreadyCreated这个缓存中 this.alreadyCreated.add(beanName); } } } }
有一个双重锁检查机制,创建的Bean的名称加到alreadyCreated(类型Set)这个缓存中,在加入缓存之前需要将原先的MergedBeanDefinition设置上一个需要清除的标识符,目的是让后续从容器中获取BeanDefinition时重新合并子类和父类的BeanDefinition,这样就可以防止元数据被改动后,BeanDefinition还是按照原来的数据去创建
protected void clearMergedBeanDefinition(String beanName) { RootBeanDefinition bd = this.mergedBeanDefinitions.get(beanName); if (bd != null) { bd.stale = true; } }
clearMergedBeanDefinition回去容器中获取RootBeanDefinition实例,然后把该实例需要重新合并的状态设为true(之前提到过,只要指定了parent属性,则两个BeanDefinition就合并成一个来使用)
回到doGetBean,接下来会调用getMergedLocalBeanDefinition方法来合并子类和父类的BeanDefinition,进入到该方法里:
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
clearMergedBeanDefinition回去容器中获取RootBeanDefinition实例,然后把该实例需要重新合并的状态设为true(之前提到过,只要指定了parent属性,则两个BeanDefinition就合并成一个来使用)
回到doGetBean,接下来会调用getMergedLocalBeanDefinition方法来合并子类和父类的BeanDefinition,进入到该方法里:
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
先从mergedBeanDefinitions缓存里获取之前已经合并好的RootBeanDefinition实例,如果stale为true的话就会合并一遍BeanDefinition,随后返回。
回到doGetBean,获取到了BeanDefinition之后,就去对相关实例做合法性校验
checkMergedBeanDefinition(mbd, beanName, args);
进入到checkMergedBeanDefinition方法里:
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args) throws BeanDefinitionStoreException { if (mbd.isAbstract()) { throw new BeanIsAbstractException(beanName); } }
看一下RootBeanDefinition是否是抽象的。
回到doGetBean,尝试从BeanDefinition里获取显式的依赖关系,如果有depends-on的话就检查是否有循环依赖关系
如果没有循环依赖的话则会将相关的依赖关系注册上
registerDependentBean(dep, beanName);
public void registerDependentBean(String beanName, String dependentBeanName) { String canonicalName = canonicalName(beanName); synchronized (this.dependentBeanMap) { // computeIfAbsent:若key对应的value为空,会将第二个参数的返回值存入并返回 // dependentBeanMap中存放着当前Bean被引用的Bean的集合 // 比如当前需要实例化的是Bean的名字是userInfo,userInfo中有个Human类型的属性human // 那么就有human被userInfo引用的关系 human=[userInfo] Set<String> dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); if (!dependentBeans.add(dependentBeanName)) { return; } } synchronized (this.dependenciesForBeanMap) { Set<String> dependenciesForBean = this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8)); dependenciesForBean.add(canonicalName); } }
先获取name,之后就进入两重注册,第一重注册往dependentBeanMap中写入键值对,key是被依赖的Bean名字,value是依赖他的Bean名字列表
第二重注册往dependenciesForBeanMap中写入键值对,键值对和上面正好是相反的
回到doGetBean,执行完显式依赖关系注册之后就会递归调用getBean(dep)来将依赖的bean创建出来,往后就是根据不同的scope进行不同的创建bean的操作了,分为Singleton、Prototype和其他。
除了Prototype是直接调用createBean(beanName, mbd, args)去创建Bean实例之外,scope=其他的将createBean封装到了一个匿名参数里
进入scope.get()方法
Object get(String name, ObjectFactory<?> objectFactory);
可见后面的匿名函数实现的是ObjectFactory的getObject方法,调用createBean方法去创建适配scope的实例。
下面主要分析scope = singleton的:
if (mbd.isSingleton()) { // 这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象 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. // 显式从单例缓存中删除 bean实例 // 因为单例模式下为了解决循环依赖,可能它已经存在了,所以将其销毁 destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
进入getSingleton方法:
也是接收一个ObjectFactory对象然后实现其getObject方法。
进入createBean:
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException;
这是个抽象方法需要子类去实现。
再回到上面的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 + "'"); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { 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; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
先将一级缓存singletonObjects上锁,获取到锁之后再次尝试从一级缓存里去获取实例,以防别的线程创建好了,如果获取不到实例就开始做真正的创建了:
先看一下目前容器是否正在销毁所有的单例:
singletonsCurrentlyInDestruction是个flag。
通过验证之后会来到beforeSingletonCreation(beanName),进入:
protected void beforeSingletonCreation(String beanName) { //inCreationCheckExclusions 直接缓存当前不能加载的bean, //主要用在web容器的拦截器里,所以这里可以忽略,因为肯定是不存在的 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } }
if 的第一个条件可以忽略,第二个条件是尝试将beanName放入正在创建的单例名字列表里,添加失败则会抛异常,因为bean的正常创建流程按理是进入不到这里的,如果beanName出现在正在创建的名字列表中则表明在本次操作之前对于同一个bean的创建已经在进行了,doGetBean的时候第一步从三级缓存中获取Bean实例的时候就应该已经获取到了。
在并发场景下,两个线程在三级缓存里都没获取到单例,就会来到这里。
再回到上面的getSingleton方法,接下来就可以去创建并获取bean实例了:
newSingleton设置为true方便后续调用addSingleton来添加一级缓存。
异常处理跳过,看一下finally:
进入afterSingletonCreation:
protected void afterSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } }
由于bean实例已经创建完毕了,所以会从正在创建的bean名字列表singletonsCurrentlyInCreation中移除beanName
回到外面,接下来就会去判断是否是新创建的单例,之前标志位已经是true了,进入addSingleton:
protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { // Bean实例完成创建之后,只保留一级缓存以及注册beanName的顺序,其余的清除 this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }
执行完addSingleton之后就会返回完整的bean实例了
回到doGetBean的创建单例的逻辑中,返回完整的bean实例之后就会执行
// 如果是普通bean,直接返回,是FactoryBean,返回他的getObject bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
再看下scope为Prototype的创建:
进入beforePrototypeCreation:
protected void beforePrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal == null) { this.prototypesCurrentlyInCreation.set(beanName); } else if (curVal instanceof String) { Set<String> beanNameSet = new HashSet<>(2); beanNameSet.add((String) curVal); beanNameSet.add(beanName); this.prototypesCurrentlyInCreation.set(beanNameSet); } else { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.add(beanName); } }
向类型为ThreadLocal的prototypesCurrentlyInCreation(当前线程正在创建的Prototype的bean名字列表)去添加该bean的记录,防止循环依赖,表示这个bean正在创建中。
回到doGetBean,之后也调用了prototypeInstance = createBean(beanName, mbd, args),创建完之后将先前注册的正在创建中的Bean信息给抹除掉
afterPrototypeCreation(beanName);
protected void afterPrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal instanceof String) { this.prototypesCurrentlyInCreation.remove(); } else if (curVal instanceof Set) { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.remove(beanName); if (beanNameSet.isEmpty()) { this.prototypesCurrentlyInCreation.remove(); } } }
回到doGetBean,之后也会调用
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
获取bean实例或者beanFactory创建的bean实例
最后在看其他的情况,
根据生命周期范围选择实例化bean的合适方法来创建bean实例,比如request就是确保每个请求生成一个实例。
doGetBean最后会做一个类型检查,校验通过后返回实例:
if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean;