Bean 的创建与获取是一个比较复杂的过程,本文主要关注 bean 获取的过程。
代码 一个比较好的阅读源码的方法是 debug,可以跟踪到代码执行的每一步。如下是一段测试代码,可用于调试 getBean 方法的调用过程。
1 2 3 4 5 6 7 8 9 10 DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); RootBeanDefinition bda = new RootBeanDefinition(A.class); bda.setScope(RootBeanDefinition.SCOPE_SINGLETON); bf.registerBeanDefinition("a" , bda); bf.getBean("a" );
这里定义了一个 DefaultListableBeanFactory 作为 Spring 的 bean factory,然后为类型 A
创建了一个 RootBeanDefinition,将其 scope 设置为 singleton,并注入到 bean factory 中,最后通过 BeanFactory 接口的 getBean
方法获取该 bean 实例。
获取过程 在 IDE 中调试上面的代码,跟踪 getBean
方法的执行过程
首先看到的是 AbstractBeanFactory 的 getBean 方法,它的实现如下:
1 2 3 public Object getBean (String name) throws BeansException { return doGetBean(name, null , null , false ); }
可以看到是交给 doGetBean 方法处理的,这个方法才是具体的执行者。
doGetBean doGetBean 是 AbstractBeanFactory 类里的一个核心方法,它封装的获取 bean 的整个流程,也是我们要看的重点。它签名如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @SuppressWarnings("unchecked") protected <T> T doGetBean (final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException
转换 beanName 第一步要对 beanName 进行处理:如果是 factoryBean 则去掉前缀 &
,然后将别名转换为原始名
1 2 3 protected String transformedBeanName (String name) { return canonicalName(BeanFactoryUtils.transformedBeanName(name)); }
通过 BeanFactoryUtils.transformedBeanName(String name)
方法去掉 &
符号前缀
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static String transformedBeanName (String name) { Assert.notNull(name, "'name' must not be null" ); if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) { return name; } return transformedBeanNameCache.computeIfAbsent(name, beanName -> { do { beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()); } while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); return beanName; }); }
通过 SimpleAliasRegistry.canonicalName(String name)
方法获取原名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public String canonicalName (String name) { String canonicalName = name; String resolvedName; do { resolvedName = this .aliasMap.get(canonicalName); if (resolvedName != null ) { canonicalName = resolvedName; } } while (resolvedName != null ); return canonicalName; }
尝试从 singleton 缓存中获取 拿到了 beanName 之后,先到 singleton 缓存中查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public Object getSingleton (String beanName) { return getSingleton(beanName, true ); } protected Object getSingleton (String beanName, boolean allowEarlyReference) { Object singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this .singletonObjects) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName); if (singletonFactory != null ) { singletonObject = singletonFactory.getObject(); this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName); } } } } return singletonObject; }
因为 bean 还未创建,也不在创建过程中,所以 isSingletonCurrentlyInCreation(beanName)
返回 false
,跳过后续处理,返回 null
若从 singleton 缓存中获取到 若从缓存获取到实例,并且参数为空,首先要判断下 bean 是否正在创建中(处理循环引用),然后对 bean 进行处理,获取实际需要的 bean(比如 sharedInstance 为 factoryBean,实际需要的是它对应的实例,则在这一步处理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 if (sharedInstance != null && args == null ) { if (logger.isTraceEnabled()) { 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 = getObjectForBeanInstance(sharedInstance, name, beanName, null ); }
这里取到的是 null,即未获取到,所以继续走下面的获取 bean 流程。
若未从 singleton 缓存中获取到 第一次调 doGetBean 时,bean 还未创建,因此从缓存中取不到,会走到下面的流程
检测 Prototype 循环引用 对 prototype 的循环引用进行检测,如果是正在创建中,则说明有循环引用,则抛异常结束
1 2 3 4 5 6 7 8 9 10 11 12 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)))); }
委托给 parentBeanFactory 若 parentBeanFactory 不为空,并且当前 BeanFactory 不存在这个 bean ,则需要交给 parentBeanFactory 处理
先要获取到原始的 bean name,用于后续 getBean
1 2 3 4 5 6 7 8 9 10 11 12 13 protected String originalBeanName (String name) { String beanName = transformedBeanName(name); if (name.startsWith(FACTORY_BEAN_PREFIX)) { beanName = FACTORY_BEAN_PREFIX + beanName; } return beanName; }
如果 parentBeanFactory 是 AbstractBeanFactory 类型的实例 ,则直接调用 doGetBean 方法 否则,如果 args 不为空 ,则委托 BeanFactory 的 getBean(String name, Object... args)
方法 否则,如果 requiredType 不为空 ,则委托 BeanFactory 的 getBean (String name, ClassrequiredType) 方法 否则,委托 BeanFactory 的 getBean (String name) 方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null ) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null ) { return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } }
标记 bean 已经创建 如果要创建的 bean 不是仅用于类型检查,那么需要标记 bean 的状态为已创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 if (!typeCheckOnly) { markBeanAsCreated(beanName); } protected void markBeanAsCreated (String beanName) { if (!this .alreadyCreated.contains(beanName)) { synchronized (this .mergedBeanDefinitions) { if (!this .alreadyCreated.contains(beanName)) { clearMergedBeanDefinition(beanName); this .alreadyCreated.add(beanName); } } } }
获取 MergedBeanDefinition 所谓 MergedBeanDefinition,可以理解为合并后的 BeanDefinition。这是因为 BeanDefinition 可能存在继承关系,需要合并相关属性后才能得到完整的 BeanDefinition,进而用于创建 Bean。
获取注册的 BeanDefinition 首先要先根据 beanName 拿到已注册的 BeanDefinition
1 2 3 4 5 protected abstract BeanDefinition getBeanDefinition (String beanName) throws BeansException ;
具体是交给 DefaultListableBeanFactory 进行处理的
1 2 3 4 5 6 7 8 9 10 11 public BeanDefinition getBeanDefinition (String beanName) throws NoSuchBeanDefinitionException { BeanDefinition bd = this .beanDefinitionMap.get(beanName); if (bd == null ) { if (logger.isTraceEnabled()) { logger.trace("No bean named '" + beanName + "' found in " + this ); } throw new NoSuchBeanDefinitionException(beanName); } return bd; }
进行合并处理 已注册的 BeanDefinition 可能是 ChildBeanDefinition,还需要进一步处理
1 2 3 4 protected RootBeanDefinition getMergedBeanDefinition (String beanName, BeanDefinition bd) throws BeanDefinitionStoreException { return getMergedBeanDefinition(beanName, bd, null ); }
先尝试从 mergedBeanDefinitions 缓存获取,若未获取到,则进行下面的操作
mbd = this.mergedBeanDefinitions.get(beanName);
若该 BeanDefinition 没有 parent,则直接构造 RootBeanDefinition
1 2 3 4 5 6 if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { mbd = new RootBeanDefinition(bd); }
否则,获取 parentBean 的名字
1 2 String parentBeanName = transformedBeanName(bd.getParentName());
若和当前的不是同一个 bean,则需要合并
1 2 3 4 if (!beanName.equals(parentBeanName)) { pbd = getMergedBeanDefinition(parentBeanName); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public BeanDefinition getMergedBeanDefinition (String name) throws BeansException { String beanName = transformedBeanName(name); if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName); } return getMergedLocalBeanDefinition(beanName); }
否则,交给 parentBeanFactory 处理
1 2 3 4 5 6 7 8 9 10 11 12 BeanFactory parent = getParentBeanFactory(); if (parent instanceof ConfigurableBeanFactory) { pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); } else { throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent" ); }
深拷贝。通过 4、5 获取到的 BeanDefintion 并不直接使用,而是返回深拷贝的结果
1 2 3 mbd = new RootBeanDefinition(pbd); mbd.overrideFrom(bd);
到这里已经拿到了 MergedBeanDefinition,剩下的就是一些通用的设置
1 2 3 4 5 6 7 8 9 10 if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); } if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); }
最后,就是将处理好的 MergedBeanDefinition 放入到缓存中,以便后续使用
1 2 3 4 if (containingBd == null && isCacheBeanMetadata()) { this .mergedBeanDefinitions.put(beanName, mbd); }
进行必要的检查 若 bean 定义为 abstract 的,则直接抛出异常结束流程
1 2 3 4 5 6 protected void checkMergedBeanDefinition (RootBeanDefinition mbd, String beanName, @Nullable Object[] args) throws BeanDefinitionStoreException { if (mbd.isAbstract()) { throw new BeanIsAbstractException(beanName); } }
DependsOn 处理 若定义了 DependOn (依赖的 bean),则注册依赖关系,并且通过 getBean 方法触发这些 bean 的注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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); } } }
Singleton bean 获取 若为 Singleton Bean
则通过 getSingleton(String beanName, ObjectFactory<?> singletonFactory)
方法获取,这里会注册一个 ObjectFactory 用于获取 bean 实例,它的实质是调用 createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法。
1 2 3 4 5 6 7 8 9 10 11 12 sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } });
获取到的 bean 可能是一个 FactoryBean,而由 beanName 指定的、实际要获取的可能是由 FactoryBean 创建的 bean,因此还需要进一步处理
1 2 3 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 protected Object getObjectForBeanInstance ( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } } if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null ; if (mbd == null ) { object = getCachedObjectForFactoryBean(beanName); } if (object == null ) { FactoryBean<?> factory = (FactoryBean<?>) beanInstance; if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
Prototype bean 获取 创建前要设置正在创建的状态,防止循环引用时会用到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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); } }
与 singleton 类型不同的是,这里是直接调用 createBean 创建实例。这是因为不需要对 prototype 类型的 bean 进行缓存,每次调用都需要创建新的实例。
相关流程如下,这里也需要对 FactoryBean 进行处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Object prototypeInstance = null ; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
其他 scope 的 bean 获取 与 singeton 类型 bean 的获取类似,区别是创建不是交给 DefaultSingletonBeanRegistry 处理,而是交给对应的 Scope 处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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); }
类型处理 若指定了 requiredType,并且获取到的 bean 实例类型不匹配,则需要对类型进行转换操作。
这里首先要拿到 TypeConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 public TypeConverter getTypeConverter () { TypeConverter customConverter = getCustomTypeConverter(); if (customConverter != null ) { return customConverter; } else { SimpleTypeConverter typeConverter = new SimpleTypeConverter(); typeConverter.setConversionService(getConversionService()); registerCustomEditors(typeConverter); return typeConverter; } }
然后尝试对类型进行转换
1 2 3 4 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null ) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); }
整体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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()); } }
时序图 AbstractBeanFactory.doGetBean AbstractBeanFactory AbstractBeanFactory parentBeanFactory parentBeanFactory DefaultSingletonBeanRegistry DefaultSingletonBeanRegistry Scope Scope TypeConverter TypeConverter 转换 beanName transformedBeanName(name) 尝试从 singleton 缓存中获取 getSingleton(beanName) alt [sharedInstance != null && args == null] getObjectForBeanInstance(sharedInstance, name, beanName, null) 1. 从缓存中获取到 singleton bean alt [isPrototypeCurrentlyInCreation(beanName)] 2. 未从缓存中获取到 singleton bean,尝试下面的方式 检测到 prototype bean 循环引用 throw new BeanCurrentlyInCreationException(beanName) 获取 parentBeanFactory getParentBeanFactory() alt [parentBeanFactory != null && !containsBeanDefinition(beanName)] 存在 parentBeanFactory, 并且当前 beanfactory 里没有要找的 BeanDefinition 取到原始的 bean name originalBeanName(name) alt [parentBeanFactory instanceof AbstractBeanFactory] doGetBean(nameToLookup, requiredType, args, typeCheckOnly) 1. 是 AbstractBeanFactory 类型的实例 [args != null] getBean(nameToLookup, args) 2. args 不为空 [requiredType != null] getBean(nameToLookup, requiredType) 3. requiredType 不为空 getBean(nameToLookup) 4. 上面的条件都不符合 alt [typeCheckOnly == false] markBeanAsCreated(beanName) 标记 bean 已经创建 获取 MergedBeanDefinition getMergedLocalBeanDefinition(beanName) 进行必要的检查 checkMergedBeanDefinition(mbd, beanName, args) alt [mbd.getDependsOn() != null] 1. 注册依赖关系 2. 通过 getBean 方法触发所依赖的 bean 进行初始化 DependsOn 处理 alt [mbd.isSingleton()] getSingleton(String beanName, ObjectFactory<?> singletonFactory) getObjectForBeanInstance(sharedInstance, name, beanName, mbd) 1. Singleton bean 获取 [mbd.isPrototype()] beforePrototypeCreation(beanName) createBean(beanName, mbd, args) afterPrototypeCreation(beanName) getObjectForBeanInstance(prototypeInstance, name, beanName, mbd) 2. Prototype bean 获取 this.scopes.get(mbd.getScope()) get(String name, ObjectFactory<?> objectFactory) getObjectForBeanInstance(scopedInstance, name, beanName, mbd) 3. 其他 scope 的 bean 获取 alt [requiredType != null && !requiredType.isInstance(bean)] getTypeConverter() 类型处理 convertIfNecessary(bean, requiredType) 流程图 获取 Spring bean 的主要流程如下:
image-20200403012230353
预览:
非常棒
@匿名:
希望能对你有所帮助