上一节是Ioc容器初始化过程,初始化过程基本就是做了一件大事:在IoC容器中构建出了BeanDefinition数据结构映射.构建出数据结构映射后,却没有看到依赖注入,下面就看看是怎么依赖注入的.
首先,注意到依赖注入的过程是用户第一次向IoC容器索要Bean时触发的,在基本的IoC容器接口beanfactory中,有一个getBean的接口定义,这个接口的实现就是触发依赖注入发生的地方.当然也有例外,也就是我们可以在BeanDefinition信息中通过控制lazy-init属性来控制容器完成对Bean的预实例化。这个预实例化实际上也是一个完成依赖注入的过程,但它是在初始化的过程中完成的,
以DefaultListablebeanfactory容器为例,简短的描述下.
整个过程的图示为:
从图上看,getBean是依赖注入的起点,之后会调用createBean,下面从DefaultListablebeanfactory的基类Abstractbeanfactory中的getBean的实现来了解这个过程。
DefaultListablebeanfactory容器的getBean整个过程步骤如下:
1.从缓存获取当前beanName,看当前类型的bean是否已经被创建过,如果没有创建过,就创建一个bean。
2.如果创建过,就从当前beanfactory中获取bean,如果当前工厂取不到,就从双亲beanfactory中取,一直进行迭代查找。
4.获取当前bean的所有依赖的bean,需要对当依赖的bean进行getBean递归调用,知道依赖的bean都创建为止。
5.根据protype调用createBean创建单例,原型模式实例,或者根据自定义scope创建实例
6.对创建的bean进行类型检查,如果没问题就返回.
代码如下:
protected <T> T doGetBean( final String name,final Class<T> requiredType,final Object[] args,boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } 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 (args != null) { // Delegation to parent with explicit args. return (T) parentbeanfactory.getBean(nameToLookup,args); } else { // No args -> delegate to standard getBean method. return parentbeanfactory.getBean(nameToLookup,requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd,args); // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dependsOnBean : dependsOn) { if (isDependent(beanName,dependsOnBean)) { throw new BeanCreationException(mbd.getResourceDescription(),"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); } registerDependentBean(dependsOnBean,beanName); getBean(dependsOnBean); } } // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName,new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { 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,mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName,args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance,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,args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance,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; } }
这个过程简要概括为,getBean是依赖注入的起点,之后会调用create-Bean,下面通过createBean代码来了解这个实现过程。在这个过程中,Bean对象会依据BeanDefinition定义的要求生成。在AbstractAutowireCapablebeanfactory中实现了这个createBean,createBean不但生成了需要的Bean,还对Bean初始化进行了处理.注入过程如下图:
createBean方法如下:
/** * Central method of this class: creates a bean instance,* populates the bean instance,applies post-processors,etc. * @see #doCreateBean */ protected Object createBean(String beanName,RootBeanDefinition mbd,Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point,and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. //确认需要创建的Bean实例的类是否可以实例化 Class<?> resolvedClass = resolveBeanClass(mbd,beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),"Validation of method overrides Failed",ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //如果bean配置了PostProcessor 那么会返回proxy Object bean = resolveBeforeInstantiation(beanName,mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(),"BeanPostProcessor before instantiation of bean Failed",ex); } //创建bean Object beanInstance = doCreateBean(beanName,mbdToUse,args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
从上面接着看doCreateBean方法:
/** * Actually create the specified bean. Pre-creation processing has already happened * at this point,e.g. checking {@code postProcessBeforeInstantiation} callbacks. * <p>Differentiates between default bean instantiation,use of a * factory method,and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object doCreateBean(final String beanName,final RootBeanDefinition mbd,final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; //如果是单例,仙踪缓存中把同名bean移除 if (mbd.isSingleton()) { instanceWrapper = this.factorybeanInstanceCache.remove(beanName); } //createBeanInstance创建实例 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName,args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName); mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like beanfactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName,new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName,bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { //开始依赖注入 populateBean(beanName,instanceWrapper); if (exposedObject != null) { exposedObject = 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(),"Initialization of bean Failed",ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName,false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!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."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName,bean,mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(),"Invalid destruction signature",ex); } return exposedObject; }
从doCreateBean方法可以看出,与依赖注入关系特别密切的方法有createBeanInstance和populateBean,下面分别介绍这两个方法。在createBeanInstance中生成了Bean所包含的Java对象,这个对象的生成有很多种不同的方式,可以通过工厂方法生成,也可以通过容器的autowire特性生成,这些生成方式都是由相关的BeanDefinition来指定的。
createBeanInstance方法如下:
/** * Create a new instance for the specified bean,using an appropriate instantiation strategy: * factory method,constructor autowiring,or simple instantiation. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return BeanWrapper for the new instance * @see #instantiateUsingFactoryMethod * @see #autowireConstructor * @see #instantiateBean */ protected BeanWrapper createBeanInstance(String beanName,Object[] args) { // Make sure bean class is actually resolved at this point. Class<?> beanClass = resolveBeanClass(mbd,beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(),"Bean class isn't public,and non-public access not allowed: " + beanClass.getName()); } //使用工厂方法对bean进行实例化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName,args); } // Shortcut when re-creating the same bean... 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 autowireConstructor(beanName,null,null); } else { return instantiateBean(beanName,mbd); } } // Need to determine the constructor... //使用构造函数进行实例化,前提是有构造函数 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass,beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName,ctors,args); } // No special handling: simply use no-arg constructor. //使用默认的构造方法 return instantiateBean(beanName,mbd); }
populateBean方法如下:
/** * Populate the bean instance in the given BeanWrapper with the property values * from the bean definition. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param bw BeanWrapper with bean instance */ protected void populateBean(String beanName,BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { if (!pvs.isEmpty()) { throw new BeanCreationException( mbd.getResourceDescription(),"Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used,for example,// to support styles of field injection. boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } //开始处理autowire类型的注入,支持按bean的名字和类型 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName,bw,newPvs); } // Add property values based on autowire by type if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName,newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw,mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs,filteredPds,bw.getWrappedInstance(),beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName,pvs); } } //对bean的属性进行注入 applyPropertyValues(beanName,pvs); }
注入过程的其他细节就不再赘述了.
在Bean的创建和对象依赖注入的过程中,需要依据载入的BeanDefinition中的信息来递归地完成依赖注入。从上面的几个递归过程中可以看到,这些递归都是以getBean为入口的。一个递归是在上下文体系中查找需要的Bean和创建Bean的递归调用;另一个递归是在依赖注入时,通过递归调用容器的getBean方法,得到当前Bean的依赖Bean,同时也触发对依赖Bean的创建和注入。在对Bean的属性进行依赖注入时,解析的过程也是一个递归的过程。这样,根据依赖关系,一层一层地完成Bean的创建和注入,直到最后完成当前Bean的创建。有了这个顶层Bean的创建和对它的属性依赖注入的完成,意味着和当前Bean相关的整个依赖链的注入也完成了。
在Bean创建和依赖注入完成以后,在IoC容器中建立起一系列依靠依赖关系联系起来的Bean,这个Bean已经不是简单的Java对象了。该Bean系列以及Bean之间的依赖关系建立完成以后,通过IoC容器的相关接口方法,就可以非常方便地供上层应用使用了。继续以水桶为例,到这里,我们不但找到了水源,而且成功地把水装到了水桶中,同时对水桶里的水完成了一系列的处理,比如消毒、煮沸……尽管还是水,但经过一系列的处理以后,这些水已经是开水了,可以直接饮用了。
参考:
1.https://github.com/spring-projects/spring-framework.
2.<<Spring技术内幕>>