初始化的过程,主要完成的工作是在容器中建立 BeanDefinition 数据映射,并没有看到容器对Bean依赖关系进行注入。
假设当前IoC容器已经载入用户定义的Bean信息,依赖注入主要发生在两个阶段
正常情况下,由用户第一次向 IoC 容器索要 bean 时触发
可在 BeanDefinition 信息中通过控制 lazy-init 属性
- 来让容器完成对Bean的预实例化,即在初始化的过程中就完成某些Bean的依赖注入的过程。
1 getBean触发的依赖注入
BeanFactory
,最原始的 IoC 容器,有如下方法
- getBean
- 判断是否有 Bean,containsBean
- 判断是否单例 isSingleton
BeanFactory 只对 IoC 容器最基本的行为作了定义,不关心 Bean 是怎样定义和加载的。如果我们想知道一个工厂具体产生对象的过程,则要看这个接口的实现类。
在基本的容器接口 BeanFactory 中,有一个 getBean接口,该接口的实现就是触发依赖注入发生的地方。为进一步了解该依赖注入过程,从 DefaultListableBeanFactory的基类AbstractBeanFactory入手看看getBean的实现。
这里是对 BeanFactory 接口的实现,比如getBean接口。
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException { // 这些 getBean 接口最终都是通过调用 doGetBean 实现 return doGetBean(name, requiredType, args, false); }
返回一个实例,该实例可以是指定bean的共享或独立的
// 实际取得 Bean 的地方,即触发依赖注入 @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) { // 去掉工厂bean的前缀或者将别名转化为规范名 final String beanName = transformedBeanName(name); Object bean; // 检查是否有已注册的bean实例 // 急切地检查单例模式缓存手动注册的单例 //先从缓存中取得Bean,处理那些已经被创建过的单例Bean,这种Bean不要重复创建 Object sharedInstance = getSingleton(beanName);
getSingleton()
返回以给定名称注册的(原始)单例对象。
仅检查已经实例化的单例; 对于尚未实例化的单例bean定义,不返回Object。
此方法的主要目的是访问手动注册的单例(请参见registerSingleton )。 也可以用于以原始方式访问由已创建的bean定义定义的单例。
注意:此查找方法不知道FactoryBean前缀或别名。 在获取单例实例之前,您需要首先解析规范化的bean名称
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 != NULL_OBJECT ? singletonObject : null); }
回过头继续看工厂实现
if (sharedInstance != null && args == null) { ... //以取得 FactoryBean 的相关处理及生产结果 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }
来看看该 getObjectForBeanInstance 方法的实现,和FactoryBean有何关系呢
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
继续回过头
else { // 若早已创建该 bean 实例则会失败进入到此 // 假设处在引用循环依赖中 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 检查 bean 定义是否存在于该工厂 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // 没有找到,即不存在 -> 检查父类 String nameToLookup = originalBeanName(name); if (args != null) { // 有更精确的参数 -> 委托给父类 return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // 无参数 -> 委托给标准的 getBean 方法 return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { //根据 Bean 名取得 BeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); //递归获得当前 Bean 依赖的所有Bean,确保它们的初始化 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); getBean(dep); } } // 创建 singleton bean 的地方 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { // 调用 createBean 创建单例 bean实例 return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // 创建 prototype bean 的地方 else if (mbd.isPrototype()) { // It's a prototype -> create a ne w 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, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { 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. // 这里对创建的Bean进行类型检查,如果没有问题,就返回这个新创建的Bean,这个Bean已经是包含了依赖关系的Bean if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return 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; }
依赖注入的发生是在容器中的 BeanDefinition
数据已经建立好的前提下进行的.