bean的创建和初始化(非 bean 配置的解析和注册)
概览 Spring 提供了多种重载和覆盖的 getBean 方法,当我们在执行 beanFactory.getBean(“myBean”) 时,我们实际上是在调用 AbstractBeanFactory 中的实现:
1 2 3 public Object getBean (String name) throws BeansException { return this .doGetBean(name, null , null , false ); }
按照 Spring 中方法的命名规则,以 “do” 开头的方法一般都是真正干事的地方,doGetBean 方法也不例外,其中包含了整个创建和获取 bean 的过程,在前面的文章中我们已经简单的浏览过该方法,这里我们再看一遍,并针对其中的逻辑进行展开:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 protected <T> T doGetBean ( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = this .transformedBeanName(name); Object bean; Object sharedInstance = this .getSingleton(beanName); if (sharedInstance != null && args == null ) { bean = this .getObjectForBeanInstance(sharedInstance, name, beanName, null ); } else { if (this .isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = this .getParentBeanFactory(); if (parentBeanFactory != null && !this .containsBeanDefinition(beanName)) { String nameToLookup = this .originalBeanName(name); if (args != null ) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else { return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { this .markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = this .getMergedLocalBeanDefinition(beanName); this .checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null ) { for (String dep : dependsOn) { if (this .isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'" ); } this .registerDependentBean(dep, beanName); this .getBean(dep); } } if (mbd.isSingleton()) { sharedInstance = this .getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); bean = this .getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { Object prototypeInstance; try { this .beforePrototypeCreation(beanName); prototypeInstance = this .createBean(beanName, mbd, args); } finally { this .afterPrototypeCreation(beanName); } bean = this .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, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = this .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; } } if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return this .getTypeConverter().convertIfNecessary(bean, requiredType); } 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; }
整个方法的过程可以概括为:
获取参数 name 对应的真正的 beanName
检查缓存或者实例工厂中是否有对应的单例,若存在则进行实例化并返回对象,否则继续往下执行
执行 prototype 类型依赖检查,防止循环依赖
如果当前 beanFactory 中不存在需要的 bean,则尝试从 parentBeanFactory 中获取
将之前解析过程返得到的 GenericBeanDefinition 对象合并为 RootBeanDefinition 对象,便于后续处理
如果存在依赖的 bean,则进行递归加载
依据当前 bean 的作用域对 bean 进行实例化
如果对返回 bean 类型有要求,则进行类型检查,并按需做类型转换
返回 bean 实例
接下来我们针对各步骤中的详细过程按照需要进行逐一探究。
获取真正的 beanName 我们在调用 getBean 方法的时候传递的 name 可以是 bean 的别名,也可以是获取 factoryBean 实例的 name,所以当我们以 name 为 key 检索 bean 的时候,首先需要获取 name 对应的唯一标识 bean 的真正名称 beanName,这一过程位于 transformedBeanName(String name) 方法中:
1 2 3 protected String transformedBeanName (String name) { return this .canonicalName(BeanFactoryUtils.transformedBeanName(name)); }
上述方法首先会通过 BeanFactoryUtils 工具类方法判断是不是获取 factoryBean,如果是的话就去掉 name 前面的 “&” 字符,然后执行 canonicalName(String name) 逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 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; }
为什么这里当 resolvedName != null
的时候需要继续循环呢,这是因为一个别名所引用的不一定是一个最终的 beanName,可以是另外一个别名,这个时候就是一个链式引用的场景,我们需要继续沿着引用链往下寻找最终的 beanName。
尝试从单例集合中获取目标 bean 容器首先尝试从单例对象集合中获取 bean 实例,我们都知道单例对象在容器中只会存在一份,所以首先检查单例集合也符合常理,获取单例对象的方法如下:
1 2 3 4 public Object getSingleton (String beanName) { return this .getSingleton(beanName, true ); }
上述方法第二个参数设置为 true,即 allowEarlyReference=true
,表示允许对 bean 的早期依赖,Spring 中 bean 的依赖关系由开发者控制,具备极大的自由配置空间,如果配置不当,可能会导致循环依赖的场景,即 A 依赖于 B,而 B 又依赖于 A,当初始化 A 的时候,检测到引用的 B 还没有实例化,就会转去实例 B,实例化 B 的过程中又会发现 A 还没有实例化完成,从而又回来实例化 A,因此陷入死锁。而 allowEarlyReference 则会提前曝光 bean 的创建过程,具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 protected Object getSingleton (String beanName, boolean allowEarlyReference) { Object singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null && this .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 != NULL_OBJECT ? singletonObject : null ); }
上述方法的逻辑是 首先从存放 bean 实例的集合 singletonObjects 中获取实例, 如果实例不存在且正在创建中,则尝试从 earlySingletonObjects 中获取正在创建中的 bean 实例, 如果仍然不存在并且允许早期依赖,则将 ObjectFactory 提前曝光。
singletonObjects 和 earlySingletonObjects 的区别
两者都是以 beanName 为 key,bean 实例为 value 进行存储,区别在于 singletonObjects 存储的是实例化完成的 bean 实例, earlySingletonObjects 存储的是正在实例化中的 bean, 所以两个集合的内容也是互斥的。
从 bean 实例中获取目标对象 如果上一步我们获取到了单例 bean 实例,那么我们需要接着调用 getObjectForBeanInstance 方法,该方法在 doGetBean 的过程中被多次调用,每次我们获取到 bean 实例之后,不管是从单例集合中获取、还是实时生成各个作用域对象,我们都需要调用一次该方法,该方法的主要目的是判断当前 bean 实例是否是 FactoryBean,如果是 FactoryBean 实例,同时用户希望获取的是真正的 bean 实例(即 name 不是以 “&” 开头),此时就需要由 FactoryBean 实例创建目标 bean 实例:
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 protected Object getObjectForBeanInstance (Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { if (BeanFactoryUtils.isFactoryDereference(name) && !(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 = this .getCachedObjectForFactoryBean(beanName); } if (object == null ) { FactoryBean<?> factory = (FactoryBean<?>) beanInstance; if (mbd == null && this .containsBeanDefinition(beanName)) { mbd = this .getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = this .getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
方法首先会进行一些基础校验,如果用户希望获取的是 FactoryBean 实例,但是当前的实例明确不是 FactoryBean 实例则抛出异常,否则除非当前实例是 FactoryBean 实例,同时用户又希望获取由 FactoryBean 实例创建的对象,其余情况直接返回 bean 实例。
接下来就是处理由 FactoryBean 实例创建目标 bean 对象的过程,首先容器会尝试从缓存中获取,因为对于一些单例的 bean 来说,可能之前已经完成了创建,如果缓存不命中则执行创建过程,这里继续调用 getObjectFromFactoryBean 方法:
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 protected Object getObjectFromFactoryBean (FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && this .containsSingleton(beanName)) { synchronized (this .getSingletonMutex()) { Object object = this .factoryBeanObjectCache.get(beanName); if (object == null ) { object = this .doGetObjectFromFactoryBean(factory, beanName); Object alreadyThere = this .factoryBeanObjectCache.get(beanName); if (alreadyThere != null ) { object = alreadyThere; } else { if (object != null && shouldPostProcess) { try { object = this .postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed" , ex); } } this .factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); } } return (object != NULL_OBJECT ? object : null ); } } else { Object object = this .doGetObjectFromFactoryBean(factory, beanName); if (object != null && shouldPostProcess) { try { object = this .postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed" , ex); } } return object; } }
该方法对于单例来说,保证单例在容器中的唯一性,同时触发后置处理器,而我们期望的创建 bean 实例的逻辑位于 doGetObjectFromFactoryBean 方法中,这里才是调用我们在使用 FactoryBean 构造对象所覆盖的 getObject 方法的地方,前面的文章已经介绍过 FactoryBean,并演示了 FactoryBean 的使用方法,再来回顾一下 FactoryBean 的构成:
1 2 3 4 5 6 7 8 public interface FactoryBean <T > { T getObject () throws Exception ; Class<?> getObjectType(); boolean isSingleton () ; }
FactoryBean 接口仅仅包含 3 个方法,而 getObject 是用来真正创建对象的地方,当我们在调用 BeanFactory 的 getBean 方法不加 “&” 获取 bean 实例时,这个时候 getBean 可以看做是 getObject 方法的代理方法,而具体调用就在 doGetObjectFromFactoryBean 方法中:
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 private Object doGetObjectFromFactoryBean (final FactoryBean<?> factory, final String beanName) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null ) { AccessControlContext acc = this .getAccessControlContext(); try { object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run () throws Exception { return factory.getObject(); } }, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { 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); } if (object == null && this .isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject" ); } return object; }
上述方法中的 factory.getObject() 是我们一层层剥离外表所触及到的核心,其具体实现则交给了开发者。
创建 bean 实例 如果单例缓存集合中不存在目标 bean 实例,那么说明当前 bean 可能是一个非单例对象,或者是一个单例但却是第一次加载,如果前面的操作是获取对象,那么这里就需要真正创建对象了,在具体创建对象之前,需要做如下几步操作:
对 prototype 对象的循环依赖进行检查,如果存在循环依赖则直接抛出异常,而不尝试去解决循环依赖。
检测目标 bean 是否属于当前 BeanFactory 的管辖范围,如果不属于,同时又存在父 BeanFactory,则委托给父 BeanFactory 进行处理。
检测是不是仅仅做类型检查,如果不是则清空 merge 标记,并标记当前 bean 为已创建状态
将存储XML配置的GenericBeanDefinition实例转换成RootBeanDefinition实例,方便后续处理
检查依赖的 bean,如果存在且未实例化,则先递归实例化依赖的 bean
完成了上述流程之后,容器针对具体的作用域采取适当的方法创建对应的 bean 实例。
创建单例对象 之前尝试从单例缓存集合中获取单例对象,而能够走到这里说明之前缓存不命中,对应的单例对象还没有创建,需要现在开始实时创建,这个过程位于 getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法中,这是一个重载方法,与前面从缓存中获取单例对象的方法在参数上存在差别:
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 50 51 52 53 54 public Object getSingleton (String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' 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!)" ); } this .beforeSingletonCreation(beanName); boolean newSingleton = false ; boolean recordSuppressedExceptions = (this .suppressedExceptions == null ); if (recordSuppressedExceptions) { this .suppressedExceptions = new LinkedHashSet<Exception>(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true ; } catch (IllegalStateException ex) { 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 ; } this .afterSingletonCreation(beanName); } if (newSingleton) { this .addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null ); } }
整个方法的逻辑还是很直观的,流程概括如下:
检测 bean 是否正在其它地方被创建,是的话抛异常并中断流程
标记 bean 的状态为“正在创建中”
实例化 bean,如果过程中出现异常,则尝试从缓存中获取实例
移除 bean 的“正在创建中”的状态
将 bean 实例加入缓存,并返回实例
步骤三中的实例化 bean 是整个流程的关键所在,这里调用了参数 singletonFactory 的 getObject 方法,由前面传入的参数我们可以知道 getObject 中的逻辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 this .getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } });
所以创建 bean 的真正逻辑位于 createBean 方法中,该方法的具体实现位于 AbstractAutowireCapableBeanFactory 中:
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 protected Object createBean (String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { RootBeanDefinition mbdToUse = mbd; Class<?> resolvedClass = this .resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null ) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed" , ex); } try { Object bean = this .resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null ) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed" , ex); } Object beanInstance = this .doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'" ); } return beanInstance; }
该方法虽然叫 createBean,但仍然不是真正创建 bean 实例的地方,该方法主要还是在做一些前期准备工作,具体的流程参见代码注释,下面针对各个过程来逐一探究。
获取 class 引用 不知道你是否还记得,在对标签解析过程的探究中,对于 class 属性的解析,如果参数中传入了类加载器则会尝试获取其 class 引用,否则直接记录类的全称类名,对于前者这里的解析就是直接返回引用,而后者则需要在此对其进行解析得到对应的 class 引用:
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 protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch) throws CannotLoadBeanClassException { try { if (mbd.hasBeanClass()) { return mbd.getBeanClass(); } if (System.getSecurityManager() != null ) { return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() { @Override public Class<?> run() throws Exception { return doResolveBeanClass(mbd, typesToMatch); } }, getAccessControlContext()); } else { return this .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 ex) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } }
逻辑很清晰,如果 beanDefinition 实例中记录已经是 class 引用则直接返回,否则进行解析,即 doResolveBeanClass 方法,该方法会验证类全称类名,并利用类加载器解析获取 class 引用,具体不再展开。
处理 override 属性 Spring 中并不存在 override-method
的标签,这里的 override 指的是 和 两个标签,之前解析这两个标签时是将这两个标签配置以 MethodOverride 对象的形式记录在 beanDefinition 实例的 methodOverrides 属性中,而这里的处理主要是逐一检查所覆盖的方法是否存在,如果不存在则覆盖无效,如果存在唯一的方法,则覆盖是明确的,标记后期无需依据参数类型以及个数进行推测:
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 public void prepareMethodOverrides () throws BeanDefinitionValidationException { MethodOverrides methodOverrides = this .getMethodOverrides(); if (!methodOverrides.isEmpty()) { Set<MethodOverride> overrides = methodOverrides.getOverrides(); synchronized (overrides) { for (MethodOverride mo : overrides) { this .prepareMethodOverride(mo); } } } } protected void prepareMethodOverride (MethodOverride mo) throws BeanDefinitionValidationException { int count = ClassUtils.getMethodCountForName(this .getBeanClass(), mo.getMethodName()); if (count == 0 ) { throw new BeanDefinitionValidationException("Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + getBeanClassName() + "]" ); } else if (count == 1 ) { mo.setOverloaded(false ); } }
处理 InstantiationAwareBeanPostProcessor 接下来主要处理 InstantiationAwareBeanPostProcessor 处理器,我们先来回忆一下该处理器的作用。该处理器的接口定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { Object postProcessBeforeInstantiation (Class<?> beanClass, String beanName) throws BeansException ; boolean postProcessAfterInstantiation (Object bean, String beanName) throws BeansException ; PropertyValues postProcessPropertyValues (PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException ; }
由上述说明还是能够清晰的知道这个处理器的功能,接口中定义的方法紧挨着 bean 实例化的过程,如果我们希望在实例化前后对 bean 的定义实施一些修改,可以实现该接口并注册到 BeanFactory 中,不过需要注意一点的是处理器会对所有的 bean 生效,而筛选的逻辑需要我们自己实现。
回过头来我们继续探究这里的处理逻辑,如下首先会去解析 bean 的真正 class 引用,因为可能存在一些工厂 bean,而具体的 bean 类型还需要通过工厂方法去推测:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 protected Object resolveBeforeInstantiation (String beanName, RootBeanDefinition mbd) { Object bean = null ; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && this .hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = this .determineTargetType(beanName, mbd); if (targetType != null ) { bean = this .applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null ) { bean = this .applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null ); } return bean; }
然后就是我们之前说到的 InstantiationAwareBeanPostProcessor 中的应用实例化前置和后置处理器,代码逻辑分别如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 protected Object applyBeanPostProcessorsBeforeInstantiation (Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : this .getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null ) { return result; } } } return null ; }
1 2 3 4 5 6 7 8 9 10 11 12 public Object applyBeanPostProcessorsAfterInitialization (Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : this .getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null ) { return result; } } return result; }
当然这里的后置处理不是必然调用,而是建立在前置处理实例化了 bean 的前提下,因为真正常规实例化 bean 的过程将在接下来一步进行发生,不过如果这一步已经完成了 bean 的实例化过程,那么也就没有继续执行下去的必要,直接返回即可:
1 2 3 4 if (bean != null ) { return bean; }
实例化 bean 终于挖到了实例化 bean 的地方,实例化 bean 的逻辑还是挺复杂的,我们先来看一下主体流程,如源码中的注释,我们可以将整个过程概括为 7 个步骤:
如果是单例,尝试从缓存中获取 bean 的包装器 BeanWrapper
如果不存在对应的 Wrapper,则说明 bean 未被实例化,创建 bean 实例
应用 MergedBeanDefinitionPostProcessor
检查是否需要提前曝光,避免循环依赖
初始化 bean 实例
再次基于依存关系验证是否存在循环依赖
注册 DisposableBean
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null ; if (mbd.isSingleton()) { instanceWrapper = this .factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null ) { instanceWrapper = this .createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null ); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null ); mbd.resolvedTargetType = beanType; synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { this .applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed" , ex); } mbd.postProcessed = true ; } } boolean earlySingletonExposure = (mbd.isSingleton() && this .allowCircularReferences && this .isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { this .addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } Object exposedObject = bean; try { this .populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null ) { exposedObject = this .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 = this .getSingleton(beanName, false ); if (earlySingletonReference != null ) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this .allowRawInjectionDespiteWrapping && this .hasDependentBean(beanName)) { String[] dependentBeans = this .getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!this .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 " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example." ); } } } } try { this .registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature" , ex); } return exposedObject; }
针对上述过程,我们逐一进行探究。
1. 对于单例,尝试从缓存中获取 BeanWrapper 对象
单例对象是全局唯一的,一旦创建就常驻内存,如果对应的 bean 已经被实例化过,那么这里获取到的是 BeanWrapper 对象,BeanWrapper 可以看作是偏底层的 bean 包装器,提供了对标准 java bean 的分析和操作方法,包括获取和设置属性值、获取属性描述符,以及属性的读写特性等。
2. bean 的实例化过程
如果步骤 1 中没有获取到目标 bean 实例,则说明对应的 bean 还没有被实例化或是非单例的 bean,这个时候就需要创建对象(通过工厂方法或构造函数创建),Spring 创建对象的基本执行流程为:
如果存在工厂方法,则使用工厂方法初始化
否则,如果存在多个构造函数,则根据参数确定构造函数,并利用构造函数初始化
否则,使用默认构造函数初始化
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 protected BeanWrapper createBeanInstance (String beanName, RootBeanDefinition mbd, Object[] args) { Class<?> beanClass = this .resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } if (mbd.getFactoryMethodName() != null ) { return this .instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false ; boolean autowireNecessary = false ; if (args == null ) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null ) { resolved = true ; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return this .autowireConstructor(beanName, mbd, null , null ); } else { return this .instantiateBean(beanName, mbd); } } Constructor<?>[] ctors = this .determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return this .autowireConstructor(beanName, mbd, ctors, args); } return this .instantiateBean(beanName, mbd); }
上述源码是属于框架式的源码,描述了整个实例化的执行流程(如前面所述),接下来我们需要继续往下深入,探究各种实例化过程,以及容器确定目标构造函数的算法。
如果存在 factory-method 则说明存在工厂方法执行实例化,Spring 通过 instantiateUsingFactoryMethod 方法执行实例化过程:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 protected BeanWrapper instantiateUsingFactoryMethod (String beanName, RootBeanDefinition mbd, Object[] explicitArgs) { return new ConstructorResolver(this ).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); } public BeanWrapper instantiateUsingFactoryMethod (final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this .beanFactory.initBeanWrapper(bw); Object factoryBean; Class<?> factoryClass; boolean isStatic; String factoryBeanName = mbd.getFactoryBeanName(); if (factoryBeanName != null ) { if (factoryBeanName.equals(beanName)) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "factory-bean reference points back to the same bean definition" ); } factoryBean = this .beanFactory.getBean(factoryBeanName); if (factoryBean == null ) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "factory-bean '" + factoryBeanName + "' (or a BeanPostProcessor involved) returned null" ); } if (mbd.isSingleton() && this .beanFactory.containsSingleton(beanName)) { throw new IllegalStateException("About-to-be-created singleton instance implicitly appeared through the creation of the factory bean that its bean definition points to" ); } factoryClass = factoryBean.getClass(); isStatic = false ; } else { if (!mbd.hasBeanClass()) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "bean definition declares neither a bean class nor a factory-bean reference" ); } factoryBean = null ; factoryClass = mbd.getBeanClass(); isStatic = true ; } Method factoryMethodToUse = null ; ArgumentsHolder argsHolderToUse = null ; Object[] argsToUse = null ; if (explicitArgs != null ) { argsToUse = explicitArgs; } else { Object[] argsToResolve = null ; synchronized (mbd.constructorArgumentLock) { factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod; if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) { argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null ) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null ) { argsToUse = this .resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve); } } if (factoryMethodToUse == null || argsToUse == null ) { factoryClass = ClassUtils.getUserClass(factoryClass); Method[] rawCandidates = this .getCandidateMethods(factoryClass, mbd); List<Method> candidateSet = new ArrayList<Method>(); for (Method candidate : rawCandidates) { if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) { candidateSet.add(candidate); } } Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]); AutowireUtils.sortFactoryMethods(candidates); ConstructorArgumentValues resolvedValues = null ; boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); int minTypeDiffWeight = Integer.MAX_VALUE; Set<Method> ambiguousFactoryMethods = null ; int minNrOfArgs; if (explicitArgs != null ) { minNrOfArgs = explicitArgs.length; } else { ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); minNrOfArgs = this .resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } LinkedList<UnsatisfiedDependencyException> causes = null ; for (Method candidate : candidates) { Class<?>[] paramTypes = candidate.getParameterTypes(); if (paramTypes.length >= minNrOfArgs) { ArgumentsHolder argsHolder; if (resolvedValues != null ) { try { String[] paramNames = null ; ParameterNameDiscoverer pnd = this .beanFactory.getParameterNameDiscoverer(); if (pnd != null ) { paramNames = pnd.getParameterNames(candidate); } argsHolder = this .createArgumentArray( beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring); } catch (UnsatisfiedDependencyException ex) { if (this .beanFactory.logger.isTraceEnabled()) { this .beanFactory.logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex); } if (causes == null ) { causes = new LinkedList<UnsatisfiedDependencyException>(); } causes.add(ex); continue ; } } else { if (paramTypes.length != explicitArgs.length) { continue ; } argsHolder = new ArgumentsHolder(explicitArgs); } int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); if (typeDiffWeight < minTypeDiffWeight) { factoryMethodToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousFactoryMethods = null ; } else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight && !mbd.isLenientConstructorResolution() && paramTypes.length == factoryMethodToUse.getParameterTypes().length && !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) { if (ambiguousFactoryMethods == null ) { ambiguousFactoryMethods = new LinkedHashSet<Method>(); ambiguousFactoryMethods.add(factoryMethodToUse); } ambiguousFactoryMethods.add(candidate); } } } if (factoryMethodToUse == null ) { if (causes != null ) { UnsatisfiedDependencyException ex = causes.removeLast(); for (Exception cause : causes) { this .beanFactory.onSuppressedException(cause); } throw ex; } List<String> argTypes = new ArrayList<String>(minNrOfArgs); if (explicitArgs != null ) { for (Object arg : explicitArgs) { argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null" ); } } else { Set<ValueHolder> valueHolders = new LinkedHashSet<ValueHolder>(resolvedValues.getArgumentCount()); valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values()); valueHolders.addAll(resolvedValues.getGenericArgumentValues()); for (ValueHolder value : valueHolders) { String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) : (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null" )); argTypes.add(argType); } } String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes); throw new BeanCreationException(mbd.getResourceDescription(), beanName, "No matching factory method found: " + (mbd.getFactoryBeanName() != null ? "factory bean '" + mbd.getFactoryBeanName() + "'; " : "" ) + "factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " + "Check that a method with the specified name " + (minNrOfArgs > 0 ? "and arguments " : "" ) + "exists and that it is " + (isStatic ? "static" : "non-static" ) + "." ); } else if (void .class == factoryMethodToUse.getReturnType()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid factory method '" + mbd.getFactoryMethodName() + "': needs to have a non-void return type!" ); } else if (ambiguousFactoryMethods != null ) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Ambiguous factory method matches found in bean '" + beanName + "' " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + ambiguousFactoryMethods); } if (explicitArgs == null && argsHolderToUse != null ) { argsHolderToUse.storeCache(mbd, factoryMethodToUse); } } try { Object beanInstance; if (System.getSecurityManager() != null ) { final Object fb = factoryBean; final Method factoryMethod = factoryMethodToUse; final Object[] args = argsToUse; beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run () { return beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, beanFactory, fb, factoryMethod, args); } }, beanFactory.getAccessControlContext()); } else { beanInstance = this .beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, this .beanFactory, factoryBean, factoryMethodToUse, argsToUse); } if (beanInstance == null ) { return null ; } bw.setBeanInstance(beanInstance); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean instantiation via factory method failed" , ex); } }
方法实现真的很长!不过整个方法主要做了三件事情:
确定当前使用的是静态工厂配置还是一般工厂配置。
确定用于实例化 bean 的工厂方法。
调用工厂方法实例化 bean。
其中最复杂的是步骤 2,因为可能存在多个工厂方法的重载版本,所以需要依据给定或配置的参数个数和类型去解析确定的工厂方法,Spring 会对所有的候选工厂方法按照 public 优先,以及参数个数多的方法优先的原则,对候选方法进行排序,然后逐个比对是否满足当前指定的参数列表,依次确定具体使用哪个工厂方法来进行实例化,这个过程与我们后面介绍的通过构造方法进行实例化时确定具体构造方法的过程大同小异,后面你还会看到与此相似的解析过程。
跳出这个方法,我们继续之前的逻辑往下走,如果一个 bean 没有配置工厂方法则需要通过构造函数进行实例化,如前面所说,一个类也可能存在多个重载的构造方法,所以需要依据给定或配置的构造参数进行决策:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 protected BeanWrapper autowireConstructor ( String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) { return new ConstructorResolver(this ).autowireConstructor(beanName, mbd, ctors, explicitArgs); } public BeanWrapper autowireConstructor ( final String beanName, final RootBeanDefinition mbd, Constructor<?>[] chosenCtors, final Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this .beanFactory.initBeanWrapper(bw); Constructor<?> constructorToUse = null ; ArgumentsHolder argsHolderToUse = null ; Object[] argsToUse = null ; if (explicitArgs != null ) { argsToUse = explicitArgs; } else { Object[] argsToResolve = null ; synchronized (mbd.constructorArgumentLock) { constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod; if (constructorToUse != null && mbd.constructorArgumentsResolved) { argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null ) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null ) { argsToUse = this .resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve); } } if (constructorToUse == null ) { boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null ; int minNrOfArgs; if (explicitArgs != null ) { minNrOfArgs = explicitArgs.length; } else { ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); minNrOfArgs = this .resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } Constructor<?>[] candidates = chosenCtors; if (candidates == null ) { Class<?> beanClass = mbd.getBeanClass(); try { candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors()); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed" , ex); } } AutowireUtils.sortConstructors(candidates); int minTypeDiffWeight = Integer.MAX_VALUE; Set<Constructor<?>> ambiguousConstructors = null ; LinkedList<UnsatisfiedDependencyException> causes = null ; for (Constructor<?> candidate : candidates) { Class<?>[] paramTypes = candidate.getParameterTypes(); if (constructorToUse != null && argsToUse.length > paramTypes.length) { break ; } if (paramTypes.length < minNrOfArgs) { continue ; } ArgumentsHolder argsHolder; if (resolvedValues != null ) { try { String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length); if (paramNames == null ) { ParameterNameDiscoverer pnd = this .beanFactory.getParameterNameDiscoverer(); if (pnd != null ) { paramNames = pnd.getParameterNames(candidate); } } argsHolder = this .createArgumentArray( beanName, mbd, resolvedValues, bw, paramTypes, paramNames, this .getUserDeclaredConstructor(candidate), autowiring); } catch (UnsatisfiedDependencyException ex) { if (this .beanFactory.logger.isTraceEnabled()) { this .beanFactory.logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex); } if (causes == null ) { causes = new LinkedList<UnsatisfiedDependencyException>(); } causes.add(ex); continue ; } } else { if (paramTypes.length != explicitArgs.length) { continue ; } argsHolder = new ArgumentsHolder(explicitArgs); } int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); if (typeDiffWeight < minTypeDiffWeight) { constructorToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousConstructors = null ; } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { if (ambiguousConstructors == null ) { ambiguousConstructors = new LinkedHashSet<Constructor<?>>(); ambiguousConstructors.add(constructorToUse); } ambiguousConstructors.add(candidate); } } if (constructorToUse == null ) { if (causes != null ) { UnsatisfiedDependencyException ex = causes.removeLast(); for (Exception cause : causes) { this .beanFactory.onSuppressedException(cause); } throw ex; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)" ); } else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Ambiguous constructor matches found in bean '" + beanName + "' (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + ambiguousConstructors); } if (explicitArgs == null ) { argsHolderToUse.storeCache(mbd, constructorToUse); } } try { Object beanInstance; if (System.getSecurityManager() != null ) { final Constructor<?> ctorToUse = constructorToUse; final Object[] argumentsToUse = argsToUse; beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run () { return beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, beanFactory, ctorToUse, argumentsToUse); } }, beanFactory.getAccessControlContext()); } else { beanInstance = this .beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, this .beanFactory, constructorToUse, argsToUse); } bw.setBeanInstance(beanInstance); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean instantiation via constructor failed" , ex); } }
整个方法的设计思想与前面通过工厂方法实例化对象相同,具体可参考注释,不再展开,而如果没有指定或配置构造参数,容器会采用默认的构造方法创建对象,该过程位于 instantiateBean 方法中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 protected BeanWrapper instantiateBean (final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this ; if (System.getSecurityManager() != null ) { beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run () { return getInstantiationStrategy().instantiate(mbd, beanName, parent); } }, getAccessControlContext()); } else { beanInstance = this .getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); this .initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed" , ex); } }
需要知晓的一点是,经过上面的流程,不管是通过通过工厂方法还是构造方法来实例化对象,到这里得到的也仅仅是一个 bean 的最初实例,还不是我们最终期望的 bean,因为后面还需要对 bean 实例进行初始化处理,注入相应的属性值等。
3. 应用 MergedBeanDefinitionPostProcessor
如果我们实现并注册了 MergedBeanDefinitionPostProcessor 处理器,希望在对 bean 初始化之前对 beanDefinition 进行处理,那么这些处理器会在这里被逐一调用:
1 2 3 4 5 6 7 8 9 10 protected void applyMergedBeanDefinitionPostProcessors (RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : this .getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }
4. 检查是否需要提前曝光,避免循环依赖
对于单例而言,Spring 会通过提前曝光的机制来尝试解决循环依赖导致的死锁问题,循环依赖导致的死锁除了发生在构造方法注入时,也可能发生在 setter 方法注入过程中,对于前者而言,容器是无法解决循环依赖问题的,只能抛出异常,而后者则可以通过提前曝光的机制来达到“先引用,后初始化”的目的,所以不会死锁,这个过程的关键代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 boolean earlySingletonExposure = ( mbd.isSingleton() && this .allowCircularReferences && this .isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { this .addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject () throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); }
方法的逻辑是先判断是否允许提前曝光,如果当前为单例 bean,且程序制定允许循环引用,同时当前 bean 正处于创建中,则会将创建 bean 的 ObjectFactory 对象加入到用于保存 beanName 和创建 bean 的工厂之间的关系的集合中:
1 2 3 4 5 6 7 8 9 10 protected void addSingletonFactory (String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null" ); synchronized (this .singletonObjects) { if (!this .singletonObjects.containsKey(beanName)) { this .singletonFactories.put(beanName, singletonFactory); this .earlySingletonObjects.remove(beanName); this .registeredSingletons.add(beanName); } } }
说明一下方法中各个变量的意义
singletonObjects:用于保存 beanName 和 bean 实例之间的关系
singletonFactories:用于保存 beanName 和 创建 bean 的工厂之间的关系
earlySingletonObjects:也是保存 beanName 和 bean 实例之间的关系,不同于 singletonObjects,当一个bean的实例放置于其中后,当bean还在创建过程中就可以通过 getBean 方法获取到
registeredSingletons:用来保存当前所有已注册的 bean
上面这段逻辑位于初始化 bean 实例之前,其用意就是当初始化一个 bean 时,如果引用了另外一个 bean,这个时候就需要转而去创建并初始化另外一个 bean,如果恰好该 bean 引用了之前的 bean 就出现了循环依赖,假设我们令第一个 bean 为 A,第二个 bean 为 B,基于这段代码的逻辑,B 就可以先给自己类型为 A 的属性注入 A 的实例(这个时候 A 还没有被初始化),然后完成初始化,此时继续回到初始化 A 的逻辑,因为都是单例,所以当 A 完成了初始化之后,B 所引用的 A 对象也就是一个完成了初始化过程的对象,而不是之前的刚刚完成对象创建还没有注入属性的实例。
5. 初始化 bean 实例
整个初始化过程包括 属性注入 和 执行初始化方法 两个步骤。我们先来看属性注入的过程,该过程位于 populateBean 方法中:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 protected void populateBean (String beanName, RootBeanDefinition mbd, BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); if (bw == null ) { if (!pvs.isEmpty()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance" ); } else { return ; } } boolean continueWithPropertyPopulation = true ; if (!mbd.isSynthetic() && this .hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : this .getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false ; break ; } } } } if (!continueWithPropertyPopulation) { return ; } if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { this .autowireByName(beanName, mbd, bw, newPvs); } if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { this .autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = this .hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : this .getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null ) { return ; } } } } if (needsDepCheck) { this .checkDependencies(beanName, mbd, filteredPds, pvs); } } this .applyPropertyValues(beanName, mbd, bw, pvs); }
该方法中会执行 InstantiationAwareBeanPostProcessor 后置处理器的 postProcessAfterInstantiation 方法逻辑,从而实现对完成实例化且还没有注入属性值的对象进行最后的更改,如果我们在 postProcessAfterInstantiation 指明不需要执行后续的属性注入过程,则方法到此结束。否则方法会检测当前的注入类型,是 byName 还是 byType,并调用相应的注入逻辑获取依赖的 bean,加入属性集合中。然后方法会调用 InstantiationAwareBeanPostProcessor 后置处理器的 postProcessPropertyValues 方法,实现在将属性值应用到 bean 实例之前的最后一次对属性值的更改,同时会依据配置执行依赖检查,以确保所有的属性都被赋值(这里的赋值是指 beanDefinition 中的属性都有对应的值,而不是指最终 bean 实例的属性是否注入了对应的值)。最后将输入值应用到 bean 实例对应的属性上。
如果当前注入类型是 byName,则容器会基于 beanName 获取依赖的 bean,并将依赖关系保存在对应的集合中,如果依赖的 bean 未被实例化则需要执行实例化逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 protected void autowireByName ( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { String[] propertyNames = this .unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { if (this .containsBean(propertyName)) { Object bean = this .getBean(propertyName); pvs.add(propertyName, bean); this .registerDependentBean(propertyName, beanName); } else { } } }
如果当前注入类型是 byType,则容器会依据类型去确定对应的 bean,并将依赖关系保存到对应的集合中,如果依赖的 bean 未被实例化则需要执行实例化逻辑,因为类型注入需要一个推断的过程,所以实现逻辑要复杂很多:
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 protected void autowireByType ( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = this .getCustomTypeConverter(); if (converter == null ) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<String>(4 ); String[] propertyNames = this .unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); if (Object.class ! = pd.getPropertyType()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); boolean eager = !PriorityOrdered.class .isAssignableFrom (bw .getWrappedClass ()) ; DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); Object autowiredArgument = this .resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null ) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { this .registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'" ); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
上述方法的核心位于 resolveDependency 方法中:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 public Object resolveDependency ( DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(this .getParameterNameDiscoverer()); if (javaUtilOptionalClass == descriptor.getDependencyType()) { return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName); } else { Object result = this .getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName); if (result == null ) { result = this .doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } } public Object doResolveDependency ( DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Object shortcut = descriptor.resolveShortcut(this ); if (shortcut != null ) { return shortcut; } Class<?> type = descriptor.getDependencyType(); Object value = this .getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null ) { if (value instanceof String) { String strVal = this .resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && this .containsBean(beanName) ? this .getMergedBeanDefinition(beanName) : null ); value = this .evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : this .getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } Object multipleBeans = this .resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null ) { return multipleBeans; } Map<String, Object> matchingBeans = this .findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { this .raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null ; } String autowiredBeanName; Object instanceCandidate; if (matchingBeans.size() > 1 ) { autowiredBeanName = this .determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null ) { if (descriptor.isRequired() || !this .indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(type, matchingBeans); } else { return null ; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null ) { autowiredBeanNames.add(autowiredBeanName); } return (instanceCandidate instanceof Class ? descriptor.resolveCandidate(autowiredBeanName, type, this ) : instanceCandidate); } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
整个解析的过程还是比较清晰的,首先会依次以确定的 @Value
注解和集合类型进行解析,如果不是这些类型,则获取匹配类型的 bean 实例集合,如果存在多个匹配,则尝试以优先级配置(比如 Primary 或 Priority)来确定首选的 bean 实例,如果仅存在唯一的匹配,则无需做推断逻辑,最后会检测当前解析得到的 bean 是不是目标 bean 实例,如果是工厂一类的 bean,则还要继续获取工厂所指代的 bean 实例。
在这一步才真正将 bean 的所有属性全部注入到 bean 实例中,之前虽然已经创建了实例,但是属性仍然存在于 beanDefinition 实例中,applyPropertyValues 会将相应属性转换成 bean 中对应属性的真实类型注入到对应属性上:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 protected void applyPropertyValues (String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { if (pvs == null || pvs.isEmpty()) { return ; } MutablePropertyValues mpvs = null ; List<PropertyValue> original; if (System.getSecurityManager() != null ) { if (bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(this .getAccessControlContext()); } } if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; if (mpvs.isConverted()) { try { bw.setPropertyValues(mpvs); return ; } catch (BeansException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values" , ex); } } original = mpvs.getPropertyValueList(); } else { original = Arrays.asList(pvs.getPropertyValues()); } TypeConverter converter = this .getCustomTypeConverter(); if (converter == null ) { converter = bw; } BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this , beanName, mbd, converter); List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size()); boolean resolveNecessary = false ; for (PropertyValue pv : original) { if (pv.isConverted()) { deepCopy.add(pv); } else { String propertyName = pv.getName(); Object originalValue = pv.getValue(); Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { convertedValue = this .convertForProperty(resolvedValue, propertyName, bw, converter); } if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); } else { resolveNecessary = true ; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values" , ex); } }
完成了属性注入,接下来容器会执行我们所熟知的 init-method 方法,不过 Spring 并不是单纯的调用一下对应的初始化方法,在整一个初始化方法 initializeBean 中,容器主要做了 4 件事情:
激活 bean 实现的 Aware 类:BeanNameAware, BeanClassLoaderAware, BeanFactoryAware
应用 BeanPostProcessor 的 postProcessBeforeInitialization
激活用户自定义的 init-method 方法,以及常用的 afterPropertiesSet 方法
应用 BeanPostProcessor 的 postProcessAfterInitialization
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 protected Object initializeBean (final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null ) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run () { invokeAwareMethods(beanName, bean); return null ; } }, getAccessControlContext()); } else { this .invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this .applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { this .invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null ), beanName, "Invocation of init method failed" , ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this .applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
6. 基于依存关系验证是否存在循环依赖
存在循环依赖会导致容器中存在残缺的 bean,这对于使用 Spring 框架的系统来说是一个极大的隐患,所以在这里最后再检测一次,确保所有需要实例化的 bean 都完成了对象的创建和初始化过程,否则系统不应该正常启动。
7. 注册 DisposableBean
Spring 允许单例或自定义作用域的 bean 实现 DisposableBean 接口:
1 2 3 4 5 6 7 8 9 10 11 12 public interface DisposableBean { void destroy () throws Exception ; }
从而在销毁对应的 bean 时能够回调实现的 destroy 方法,从而为销毁前的处理工作提供了入口,容器会利用一个 Map 集合来记录所有实现了 DisposableBean 接口的 bean:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 protected void registerDisposableBeanIfNecessary (String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null ); if (!mbd.isPrototype() && this .requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { this .registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, this .getBeanPostProcessors(), acc)); } else { Scope scope = this .scopes.get(mbd.getScope()); if (scope == null ) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'" ); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
当我们在调用 destroySingleton 销毁 bean 的时候,容器就会尝试从 DisposableBean 集合中获取当前待销毁 bean 对应的 DisposableBean 实例,如果存在则调用 destroy 方法,执行其中的自定义逻辑。
创建原型对象 创建和初始化过程调用的 createBean 方法同单例对象,不再重复撰述。
创建其它作用域对象 创建和初始化过程调用的 createBean 方法同单例对象,不再重复撰述。
类型检查和转换 我们在 getBean 的时候可以指定我们期望的返回类型 getBean(String name, Class requiredType)
,如果我们指定了那么容器在创建和初始化 bean 的最后一步需要执行类型校验,并尝试将不是期望类型的 bean 实例转换成期望类型:
1 2 3 4 5 6 7 8 9 10 11 12 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return this .getTypeConverter().convertIfNecessary(bean, requiredType); } 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()); } }
这个转换的过程还是比较复杂的,鉴于本篇已经写的够长了,就不再展开啦。
来源 https://my.oschina.net/wangzhenchao/blog/918237