Spring源码分析----IOC依赖注入
来源:互联网 发布:新浪微博粉丝数据分析 编辑:程序博客网 时间:2024/05/16 19:33
本文参考《spring技术内幕第2版》,spring4
前面对IoC容器的初始化过程进行了详细的分析,这个初始化过程的主要工作是在IoC容器中建立BeanDefinition数据映射。在此过程中并没有看到IoC容器对Bean依赖关系 进行注入,接入来进行分析
假设当前IoC容器已经载入了用户定义的Bean信息,开始分析依赖注入的原理。首先,注意到依赖注入的过程是用户第一次向IoC容器索要Bean时触发的,【当然也有例外,也就是我们可以在BeanDefinition信息中通过控制lazy-init属性来让容器完成对Bean的预实例化,这个预实例化实际上也是一个完成依赖注入的过程,但它是在初始化的过程中完成的,稍后分析这一过程】。当用户向IoC容器索要Bean时,在基本的IoC容器接口BeanFactory中,有一个getBean的接口定义,这个接口的实现就是触发依赖注入发生的地方。
为了进一步了解这个依赖注入过程的实现,下面从DefaultListableBeanFactory的基类AbstractBeanFactory入手去看getBean的实现。
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String var1) throws BeansException; <T> T getBean(String var1, Class<T> var2) throws BeansException; <T> T getBean(Class<T> var1) throws BeansException; Object getBean(String var1, Object... var2) throws BeansException; <T> T getBean(Class<T> var1, Object... var2) throws BeansException; boolean containsBean(String var1); boolean isSingleton(String var1) throws NoSuchBeanDefinitionException; boolean isPrototype(String var1) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException; Class<?> getType(String var1) throws NoSuchBeanDefinitionException; String[] getAliases(String var1);}
----------------------------------// BeanFactory实现子类 public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory /*这里是对BeanFactory接口的实现,比如getBean接口方法 这些getBean接口方法最终是通过调用doGetBean来实现的*/ public Object getBean(String name) throws BeansException { return this.doGetBean(name, (Class)null, (Object[])null, false); } public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return this.doGetBean(name, requiredType, (Object[])null, false); } public Object getBean(String name, Object... args) throws BeansException { return this.doGetBean(name, (Class)null, args, false); } public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException { return this.doGetBean(name, requiredType, args, false); } // 这里是实际取得bean的地方,也是触发依赖注入的入口 protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = this.transformedBeanName(name); // 先从缓存中取得Bean,处理那些已经被创建过的单件模式的Bean,对这种Bean的请求不需要重复地创建 Object sharedInstance = this.getSingleton(beanName); Object bean; if(sharedInstance != null && args == null) { if(this.logger.isDebugEnabled()) { if(this.isSingletonCurrentlyInCreation(beanName)) { this.logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference"); } else { this.logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'"); } } /* [FactoryBean的实现]---->这里的getObjectForBeanInstance完成的是FactoryBean的相关处理,以取得FactoryBean的生产结果 BeanFactory和FactoryBean的区别已经在前面讲过,后面详细分析*/ bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); } else { if(this.isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } /* 这里对IoC容器中的BeanFactory是否存在进行检查,检查是否能在当前的BeanFactory中取得需要的Bean. 如果在当前的工厂中取不到,则到双亲BeanFactory中去取; 如果当前的双亲工厂取不到,那就顺着双亲BeanFactory链一直向上找*/ BeanFactory ex = this.getParentBeanFactory(); if(ex != null && !this.containsBeanDefinition(beanName)) { String var24 = this.originalBeanName(name); if(args != null) { return ex.getBean(var24, args); } return ex.getBean(var24, requiredType); } if(!typeCheckOnly) { this.markBeanAsCreated(beanName); } try {// 这里根据Bean的名字取得BeanDefinition final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName); this.checkMergedBeanDefinition(ex1, beanName, args); // 获取当前的Bean的所有依赖Bean,这样会触发getBean的递归调用,直到取得一个没有任何依赖的Bean为止 String[] dependsOn = ex1.getDependsOn(); String[] scopeName; if(dependsOn != null) { scopeName = dependsOn; int scope = dependsOn.length; for(int ex2 = 0; ex2 < scope; ++ex2) { String dependsOnBean = scopeName[ex2]; if(this.isDependent(beanName, dependsOnBean)) { throw new BeanCreationException(ex1.getResourceDescription(), beanName, "Circular depends-on relationship between \'" + beanName + "\' and \'" + dependsOnBean + "\'"); } this.registerDependentBean(dependsOnBean, beanName); this.getBean(dependsOnBean); } }/* 这里通过调用createBean方法创建Singleton bean的实例,这有一个回调函数getObject,会在getSingleton中调用ObjectFactory的createBean*/ if(ex1.isSingleton()) { sharedInstance = this.getSingleton(beanName, new ObjectFactory() { public Object getObject() throws BeansException { try { return AbstractBeanFactory.this.createBean(beanName, ex1, args); // -------> } catch (BeansException var2) { AbstractBeanFactory.this.destroySingleton(beanName); throw var2; } } }); bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1); } else if(ex1.isPrototype()) { // 这里是创建prototype bean的地方 scopeName = null; Object var25; try { this.beforePrototypeCreation(beanName); var25 = this.createBean(beanName, ex1, args);//-----> } finally { this.afterPrototypeCreation(beanName); } bean = this.getObjectForBeanInstance(var25, name, beanName, ex1); } else { String var26 = ex1.getScope(); Scope var27 = (Scope)this.scopes.get(var26); if(var27 == null) { throw new IllegalStateException("No Scope registered for scope \'" + var26 + "\'"); } try { Object var28 = var27.get(beanName, new ObjectFactory() { public Object getObject() throws BeansException { AbstractBeanFactory.this.beforePrototypeCreation(beanName); Object var1; try { var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args); } finally { AbstractBeanFactory.this.afterPrototypeCreation(beanName); } return var1; } }); bean = this.getObjectForBeanInstance(var28, name, beanName, ex1); } catch (IllegalStateException var21) { throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' 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", var21); } } } catch (BeansException var23) { this.cleanupAfterBeanCreationFailure(beanName); throw var23; } }/* 这里对创建的Bean进行类型检查,如果没有问题,就返回这个新创建的Bean, 这个Bean已经是包含了依赖关系的bean */ if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return this.getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException var22) { if(this.logger.isDebugEnabled()) { this.logger.debug("Failed to convert bean \'" + name + "\' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } else { return bean; } } protected abstract Object createBean(String var1, RootBeanDefinition var2, Object[] var3) throws BeanCreationException;上面就是依赖注入的入口,在这里触发了依赖注入,而依赖注入的发生是在容器中的BeanDefinition数据已经建立好的前提下进行的。
下面详解分析依赖注入的过程。重点来说,getBean是依赖注入的起点,之后会调用createBean.。
// public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory /** 在这个方法中,Bean对象会依据BeanDefinition定义的要求生成 该方法不但生成了需要的Bean,还以Bean初始化进行了处理,如实现了BeanDefinition中的init-method属性定义,Bean后置处理器等*/ protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if(this.logger.isDebugEnabled()) { this.logger.debug("Creating instance of bean \'" + beanName + "\'"); }// 这里判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入 this.resolveBeanClass(mbd, beanName, new Class[0]); try { mbd.prepareMethodOverrides(); } catch (BeanDefinitionValidationException var5) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", var5); } Object beanInstance; try { // 如果Bean配置了PostProcessor,那么这里返回的是一个proxy beanInstance = this.resolveBeforeInstantiation(beanName, mbd); if(beanInstance != null) { return beanInstance; } } catch (Throwable var6) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var6); }// 这里是创建Bean的调用 beanInstance = this.doCreateBean(beanName, mbd, args); //----------------------> if(this.logger.isDebugEnabled()) { this.logger.debug("Finished creating instance of bean \'" + beanName + "\'"); } return beanInstance; } // 这里是Bean怎样生成的 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {// 这个BeanWrapper是用来持有创建出来的Bean对象的 BeanWrapper instanceWrapper = null;// 如果是Singleton,先把缓存中的同名Bean清除 if(mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName); }// 这里是创建Bean的地方,由createBeanInstance来完成的 if(instanceWrapper == null) { instanceWrapper = this.createBeanInstance(beanName, mbd, args); // --------------------> } final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null; Class beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null; Object earlySingletonExposure = mbd.postProcessingLock; synchronized(mbd.postProcessingLock) { if(!mbd.postProcessed) { this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } boolean var19 = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName); if(var19) { if(this.logger.isDebugEnabled()) { this.logger.debug("Eagerly caching bean \'" + beanName + "\' to allow for resolving potential circular references"); } this.addSingletonFactory(beanName, new ObjectFactory() { public Object getObject() throws BeansException { return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean); } }); }// 这里是对Bean的初始化,依赖注入往往在这里发生,// 这个exposeObject在初始化处理完以后会返回作为依赖注入完成后的Bean Object exposedObject = bean; try { this.populateBean(beanName, mbd, instanceWrapper); // -----------------> if(exposedObject != null) { exposedObject = this.initializeBean(beanName, exposedObject, mbd); // ------------------> } } catch (Throwable var17) { if(var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) { throw (BeanCreationException)var17; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var17); } if(var19) { Object ex = this.getSingleton(beanName, false); if(ex != null) { if(exposedObject == bean) { exposedObject = ex; } else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) { String[] dependentBeans = this.getDependentBeans(beanName); LinkedHashSet actualDependentBeans = new LinkedHashSet(dependentBeans.length); String[] var12 = dependentBeans; int var13 = dependentBeans.length; for(int var14 = 0; var14 < var13; ++var14) { String dependentBean = var12[var14]; 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); return exposedObject; } catch (BeanDefinitionValidationException var16) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16); } }在这里看到,与依赖注入关系特别密切的方法createBeanInstance和populateBean,下面分别介绍这两个方法。
/** 在这个方法中生成了Bean所包含的Java对象,这个对象的生成有很多种不同的方式, 可以通过工厂方法或者容器的autowire特性生成,这些生成方式都是由相关的BeanDefinition来指定的*/ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {// 确认需要创建的Bean实例的类可以实例化 Class beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]); 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()); } else if(mbd.getFactoryMethodName() != null) { // 这里使用工厂方法对Bean进行实例化 return this.instantiateUsingFactoryMethod(beanName, mbd, args); } else { boolean resolved = false; boolean autowireNecessary = false; if(args == null) { Object ctors = mbd.constructorArgumentLock; synchronized(mbd.constructorArgumentLock) { if(mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if(resolved) { return autowireNecessary?this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null):this.instantiateBean(beanName, mbd); } else {// 使用构造函数进行实例化 Constructor[] ctors1 = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName); return ctors1 == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)?this.instantiateBean(beanName, mbd):this.autowireConstructor(beanName, mbd, ctors1, args); } } } // 最常见的实例化过程,使用构造函数进行实例化 protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object ex; if(System.getSecurityManager() != null) { ex = AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return AbstractAutowireCapableBeanFactory.this.getInstantiationStrategy().instantiate(mbd, beanName, AbstractAutowireCapableBeanFactory.this); } }, this.getAccessControlContext()); } else {/* 使用默认的实例化策略对Bean进行实例化,默认的实例化策略是CglibSubclassingInstantiationStrategy, 也就是CGLIB来对Bean进行实例化*/ ex = this.getInstantiationStrategy().instantiate(mbd, beanName, this); // -----------------> } BeanWrapperImpl bw = new BeanWrapperImpl(ex); this.initBeanWrapper(bw); return bw; } catch (Throwable var6) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6); } }这里用CGLIB对Bean进行实例化。CGLIB是一个常用的字节码生成器的类库,它提供一系列API来提供生成和转换Java的字节码的功能。在Spring AOP中也使用CGLIB对Java的字节码进行增强。在IoC容器中,要了解怎样使用CGLIB来生成Bean对象,需要看一下SimpleInstantiationStrategy类。这个Strategy是Spring用来生成Bean对象的默认类,它提供了两种实例化Java对象的方法,一种是通过BeanUtils,它使用JVM的反射功能,一种是通过前面提到的CGLIB来生成,如下:
public interface InstantiationStrategy { Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3) throws BeansException; // -------------> Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3, Constructor<?> var4, Object[] var5) throws BeansException; Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3, Object var4, Method var5, Object[] var6) throws BeansException;}public class SimpleInstantiationStrategy implements InstantiationStrategy {...... // 该类这个方法生成 java对象 public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) { if(beanDefinition.getMethodOverrides().isEmpty()) { Object var5 = beanDefinition.constructorArgumentLock; // 这里取得指定的构造器或者生成对象的工厂方法来对Bean进行实例化 Constructor constructorToUse; synchronized(beanDefinition.constructorArgumentLock) { constructorToUse = (Constructor)beanDefinition.resolvedConstructorOrFactoryMethod; if(constructorToUse == null) { final Class clazz = beanDefinition.getBeanClass(); if(clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if(System.getSecurityManager() != null) { constructorToUse = (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction() { public Constructor<?> run() throws Exception { return clazz.getDeclaredConstructor((Class[])null); } }); } else { constructorToUse = clazz.getDeclaredConstructor((Class[])null); } beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Exception var9) { throw new BeanInstantiationException(clazz, "No default constructor found", var9); } } } /* 通过BeanUtils进行实例化,这个BeanUtils的实例化通过Constructor来实例化Bean, 在BeanUtils中可以看到具体的调用ctor.newInstance(args))*/ return BeanUtils.instantiateClass(constructorToUse, new Object[0]); } else { // 使用CGLIB来实例化对象 return this.instantiateWithMethodInjection(beanDefinition, beanName, owner); } }......}到这里已经分析了实例化Bean对象的整个过程。
在实例化Bean对象生成的基础上,再介绍一下Spring是怎样对这些对象进行处理的,也就是Bean对象生成以后,怎样把这些Bean对象的依赖关系设置好,完成整个依赖注入过程。这个过程涉及对各种Bean对象的属性的处理过程(即依赖关系处理的过程),这个依赖关系处理的依据就是已经解析得到的BeanDefinition。要详细了解这个过程,需要回到前面的pupulateBean方法,代码如下:
// public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { /* 这里取得在BeanDefinition中设置的property值,这些property来自对BeanDefinition的解析,具体的解析过程可以参看载入和解析BeanDefinition的分析*/ Object pvs = mbd.getPropertyValues(); if(bw == null) { if(!((PropertyValues)pvs).isEmpty()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } } else { boolean continueWithPropertyPopulation = true; if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) { Iterator hasInstAwareBpps = this.getBeanPostProcessors().iterator(); while(hasInstAwareBpps.hasNext()) { BeanPostProcessor needsDepCheck = (BeanPostProcessor)hasInstAwareBpps.next(); if(needsDepCheck instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor filteredPds = (InstantiationAwareBeanPostProcessor)needsDepCheck; if(!filteredPds.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if(continueWithPropertyPopulation) {// 开始进行依赖注入过程,先处理autowire的注入 if(mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) { MutablePropertyValues hasInstAwareBpps1 = new MutablePropertyValues((PropertyValues)pvs); // 这里是对autowire注入的处理,可以根据Bean的名字或类型为完成Bean的autowire if(mbd.getResolvedAutowireMode() == 1) { this.autowireByName(beanName, mbd, bw, hasInstAwareBpps1); } if(mbd.getResolvedAutowireMode() == 2) { this.autowireByType(beanName, mbd, bw, hasInstAwareBpps1); } pvs = hasInstAwareBpps1; } boolean hasInstAwareBpps2 = this.hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck1 = mbd.getDependencyCheck() != 0; if(hasInstAwareBpps2 || needsDepCheck1) { PropertyDescriptor[] filteredPds1 = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if(hasInstAwareBpps2) { Iterator var9 = this.getBeanPostProcessors().iterator(); while(var9.hasNext()) { BeanPostProcessor bp = (BeanPostProcessor)var9.next(); if(bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp; pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds1, bw.getWrappedInstance(), beanName); if(pvs == null) { return; } } } } if(needsDepCheck1) { this.checkDependencies(beanName, mbd, filteredPds1, (PropertyValues)pvs); } }// 对属性进行注入 this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs); // ---------------> } } } // 具体的对属性进行解析然后注入的过程 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { if(pvs != null && !pvs.isEmpty()) { MutablePropertyValues mpvs = null; if(System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext()); } List original; if(pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues)pvs; if(mpvs.isConverted()) { try { bw.setPropertyValues(mpvs); return; } catch (BeansException var18) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18); } } original = mpvs.getPropertyValueList(); } else { original = Arrays.asList(pvs.getPropertyValues()); } Object converter = this.getCustomTypeConverter(); if(converter == null) { converter = bw; } // 注意这个BnDefinitionValueResolver对BeanDefinition的解析是在这个valueResolver中完成的 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter); // 这里为解析值创建一个副本,副本的数据将会被注入到Bean中 ArrayList deepCopy = new ArrayList(original.size()); boolean resolveNecessary = false; Iterator ex = original.iterator(); while(true) { while(ex.hasNext()) { PropertyValue pv = (PropertyValue)ex.next(); 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, (TypeConverter)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(); }// 这里是依赖注入发生的地方,会在BeanWrapperImpl中完成 try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); // -----------------> return; } catch (BeansException var19) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19); } } } }这里通过使用BeanDefinitionResolver来对BeanDefinition进行解析,然后注入到property中。
下面到BeanDefinitionValueResolver中去看一下解析过程的实现,
------------------------------------------// class BeanDefinitionValueResolver // 这个方法包含了所有对注入类型的处理 public Object resolveValueIfNecessary(Object argName, Object value) {// 这里对RuntimeBeanReference进行解析,该类是在对BeanDefinition进行解析时生成的数据对象 if(value instanceof RuntimeBeanReference) { RuntimeBeanReference typedStringValue6 = (RuntimeBeanReference)value; return this.resolveReference(argName, typedStringValue6); // -------------> } else if(value instanceof RuntimeBeanNameReference) { String typedStringValue5 = ((RuntimeBeanNameReference)value).getBeanName(); typedStringValue5 = String.valueOf(this.doEvaluate(typedStringValue5)); if(!this.beanFactory.containsBean(typedStringValue5)) { throw new BeanDefinitionStoreException("Invalid bean name \'" + typedStringValue5 + "\' in bean reference for " + argName); } else { return typedStringValue5; } } else if(value instanceof BeanDefinitionHolder) { BeanDefinitionHolder typedStringValue4 = (BeanDefinitionHolder)value; return this.resolveInnerBean(argName, typedStringValue4.getBeanName(), typedStringValue4.getBeanDefinition()); } else if(value instanceof BeanDefinition) { BeanDefinition typedStringValue3 = (BeanDefinition)value; String valueObject3 = "(inner bean)#" + ObjectUtils.getIdentityHexString(typedStringValue3); return this.resolveInnerBean(argName, valueObject3, typedStringValue3); } else if(value instanceof ManagedArray) { // 这里对ManagedArray ManagedArray typedStringValue2 = (ManagedArray)value; Class valueObject2 = typedStringValue2.resolvedElementType; if(valueObject2 == null) { String ex2 = typedStringValue2.getElementTypeName(); if(StringUtils.hasText(ex2)) { try { valueObject2 = ClassUtils.forName(ex2, this.beanFactory.getBeanClassLoader()); typedStringValue2.resolvedElementType = valueObject2; } catch (Throwable var9) { throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error resolving array type for " + argName, var9); } } else { valueObject2 = Object.class; } } return this.resolveManagedArray(argName, (List)value, valueObject2); } else if(value instanceof ManagedList) { return this.resolveManagedList(argName, (List)value); } else if(value instanceof ManagedSet) { return this.resolveManagedSet(argName, (Set)value); } else if(value instanceof ManagedMap) { return this.resolveManagedMap(argName, (Map)value); } else if(value instanceof ManagedProperties) { Properties typedStringValue1 = (Properties)value; Properties valueObject1 = new Properties(); Object propKey; Object propValue; for(Iterator ex1 = typedStringValue1.entrySet().iterator(); ex1.hasNext(); valueObject1.put(propKey, propValue)) { Entry propEntry = (Entry)ex1.next(); propKey = propEntry.getKey(); propValue = propEntry.getValue(); if(propKey instanceof TypedStringValue) { propKey = this.evaluate((TypedStringValue)propKey); } if(propValue instanceof TypedStringValue) { propValue = this.evaluate((TypedStringValue)propValue); } } return valueObject1; } else if(value instanceof TypedStringValue) { TypedStringValue typedStringValue = (TypedStringValue)value; Object valueObject = this.evaluate(typedStringValue); try { Class ex = this.resolveTargetType(typedStringValue); return ex != null?this.typeConverter.convertIfNecessary(valueObject, ex):valueObject; } catch (Throwable var10) { throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error converting typed String value for " + argName, var10); } } else { return this.evaluate(value); } } // 这里以一个例子 // 对RuntimeBeanReference类型的注入在resolveReference中,其他的去相应的方法 private Object resolveReference(Object argName, RuntimeBeanReference ref) { try { // 从RuntimeBeanReference取得reference的名字,这个类是在载入BeanDefinition时根据配置生成的 String ex = ref.getBeanName(); ex = String.valueOf(this.doEvaluate(ex)); // 如果ref是在双亲IoC容器中,那就到双亲IoC容器中去获取 if(ref.isToParent()) { if(this.beanFactory.getParentBeanFactory() == null) { throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Can\'t resolve reference to bean \'" + ex + "\' in parent factory: no parent factory available"); } else { return this.beanFactory.getParentBeanFactory().getBean(ex); } } else {/* 在当前IoC容器中取得Bean,这里会触发一个getBean的过程如果依赖注入没有发生,这里会触发相应的依赖注入的发生*/ Object bean = this.beanFactory.getBean(ex); this.beanFactory.registerDependentBean(ex, this.beanName); return bean; } } catch (BeansException var5) { throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean \'" + ref.getBeanName() + "\' while setting " + argName, var5); } }在完成这个解析过程后,已经为依赖注入准备了条件,这是真正把Bean对象设置到它所依赖的另一个Bean的属性中去的地方,其中处理的属性是各种各样的。
依赖注入的发生是在BeanWrapper的setPropertyValues中实现的,具体的完成却是在BeanWrapper的子类BeanWrapperImpl中实现的,代码如下:
public interface PropertyAccessor {...... void setPropertyValue(PropertyValue var1) throws BeansException;......}--------------------//public abstract class AbstractPropertyAccessor extends TypeConverterSupport implements ConfigurablePropertyAccessor { public void setPropertyValues(PropertyValues pvs) throws BeansException { this.setPropertyValues(pvs, false, false); } public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException {...... this.setPropertyValue(pv);...... } public void setPropertyValue(PropertyValue pv) throws BeansException { this.setPropertyValue(pv.getName(), pv.getValue()); } public abstract void setPropertyValue(String var1, Object var2) throws BeansException;-------------------------// public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyAccessor { public void setPropertyValue(String propertyName, Object value) throws BeansException {...... nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value)); } protected void setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException { String propertyName = tokens.canonicalName; String actualName = tokens.actualName; Object oldValue; if(tokens.keys != null) { // 设置tokens的索引和keys AbstractNestablePropertyAccessor.PropertyTokenHolder ph = new AbstractNestablePropertyAccessor.PropertyTokenHolder(); ph.canonicalName = tokens.canonicalName; ph.actualName = tokens.actualName; ph.keys = new String[tokens.keys.length - 1]; System.arraycopy(tokens.keys, 0, ph.keys, 0, tokens.keys.length - 1); try {// 该方法取得Bean中对注入对象的引用,比如Array,List,Map,Set等 oldValue = this.getPropertyValue(ph); } catch (NotReadablePropertyException var20) { throw new NotWritablePropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced in indexed property path \'" + propertyName + "\'", var20); } String ex = tokens.keys[tokens.keys.length - 1]; if(oldValue == null) { if(!this.isAutoGrowNestedPaths()) { throw new NullValueInNestedPathException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced in indexed property path \'" + propertyName + "\': returned null"); } int pce = tokens.canonicalName.lastIndexOf(91); ph.canonicalName = tokens.canonicalName.substring(0, pce); oldValue = this.setDefaultValue(ph); } Class cause; Object typeDescriptor; Object convertedMapValue; AbstractNestablePropertyAccessor.PropertyHandler var27; if(oldValue.getClass().isArray()) { // 这里对Array进行注入 var27 = this.getLocalPropertyHandler(actualName); cause = oldValue.getClass().getComponentType(); int mapValueType = Integer.parseInt(ex); Object map = null; try { if(this.isExtractOldValueForEditor() && mapValueType < Array.getLength(oldValue)) { map = Array.get(oldValue, mapValueType); } typeDescriptor = this.convertIfNecessary(propertyName, map, pv.getValue(), cause, var27.nested(tokens.keys.length)); int convertedMapKey = Array.getLength(oldValue); if(mapValueType >= convertedMapKey && mapValueType < this.autoGrowCollectionLimit) { Class oldValue1 = oldValue.getClass().getComponentType(); convertedMapValue = Array.newInstance(oldValue1, mapValueType + 1); System.arraycopy(oldValue, 0, convertedMapValue, 0, convertedMapKey); this.setPropertyValue(actualName, convertedMapValue); oldValue = this.getPropertyValue(actualName); } Array.set(oldValue, mapValueType, typeDescriptor); } catch (IndexOutOfBoundsException var19) { throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid array index in property path \'" + propertyName + "\'", var19); } } else { Object var37; if(oldValue instanceof List) { // 对List进行注入 var27 = this.getPropertyHandler(actualName); cause = var27.getCollectionType(tokens.keys.length); List var31 = (List)oldValue; int var34 = Integer.parseInt(ex); typeDescriptor = null; if(this.isExtractOldValueForEditor() && var34 < var31.size()) { typeDescriptor = var31.get(var34); } var37 = this.convertIfNecessary(propertyName, typeDescriptor, pv.getValue(), cause, var27.nested(tokens.keys.length)); int var38 = var31.size(); if(var34 >= var38 && var34 < this.autoGrowCollectionLimit) { for(int var40 = var38; var40 < var34; ++var40) { try { var31.add((Object)null); } catch (NullPointerException var18) { throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot set element with index " + var34 + " in List of size " + var38 + ", accessed using property path \'" + propertyName + "\': List does not support filling up gaps with null elements"); } } var31.add(var37); } else { try { var31.set(var34, var37); } catch (IndexOutOfBoundsException var17) { throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid list index in property path \'" + propertyName + "\'", var17); } } } else { if(!(oldValue instanceof Map)) { // 对Map进行注入 throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Property referenced in indexed property path \'" + propertyName + "\' is neither an array nor a List nor a Map; returned value was [" + oldValue + "]"); } var27 = this.getLocalPropertyHandler(actualName); cause = var27.getMapKeyType(tokens.keys.length); Class var32 = var27.getMapValueType(tokens.keys.length); Map var35 = (Map)oldValue; TypeDescriptor var36 = TypeDescriptor.valueOf(cause); var37 = this.convertIfNecessary((String)null, (Object)null, ex, cause, var36); Object var39 = null; if(this.isExtractOldValueForEditor()) { var39 = var35.get(var37); } convertedMapValue = this.convertIfNecessary(propertyName, var39, pv.getValue(), var32, var27.nested(tokens.keys.length)); var35.put(var37, convertedMapValue); } } } else { AbstractNestablePropertyAccessor.PropertyHandler var25 = this.getLocalPropertyHandler(actualName); if(var25 == null || !var25.isWritable()) { if(pv.isOptional()) { if(logger.isDebugEnabled()) { logger.debug("Ignoring optional value for property \'" + actualName + "\' - property not found on bean class [" + this.getRootClass().getName() + "]"); } return; } else { throw this.createNotWritablePropertyException(propertyName); } } oldValue = null; PropertyChangeEvent var28; try { Object var26 = pv.getValue(); Object var29 = var26; if(!Boolean.FALSE.equals(pv.conversionNecessary)) { if(pv.isConverted()) { var29 = pv.getConvertedValue(); } else { if(this.isExtractOldValueForEditor() && var25.isReadable()) { try { oldValue = var25.getValue(); } catch (Exception var21) { Exception var33 = var21; if(var21 instanceof PrivilegedActionException) { var33 = ((PrivilegedActionException)var21).getException(); } if(logger.isDebugEnabled()) { logger.debug("Could not read previous value of property \'" + this.nestedPath + propertyName + "\'", var33); } } } var29 = this.convertForProperty(propertyName, oldValue, var26, var25.toTypeDescriptor()); } pv.getOriginalPropertyValue().conversionNecessary = Boolean.valueOf(var29 != var26); }// 这里取得注入属性的set方法,通过反射机制,把对象注入进去 var25.setValue(this.wrappedObject, var29); } catch (TypeMismatchException var22) { throw var22; } catch (InvocationTargetException var23) { var28 = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue()); if(var23.getTargetException() instanceof ClassCastException) { throw new TypeMismatchException(var28, var25.getPropertyType(), var23.getTargetException()); } Throwable var30 = var23.getTargetException(); if(var30 instanceof UndeclaredThrowableException) { var30 = var30.getCause(); } throw new MethodInvocationException(var28, var30); } catch (Exception var24) { var28 = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue()); throw new MethodInvocationException(var28, var24); } } }这样就完成了对各种Bean属性的依赖注入过程。
在Bean的创建和对象依赖注入的过程中,需要依据BeanDefinition中的信息来递归地完成依赖注入。从上面的几个递归过程中可以看到,这些递归都是以getBean为入口。一个递归是在上下文体系中查找需要的Bean和创建Bean的递归调用,另一个递归是在依赖注入时,通过递归调用容器的getBean方法,得到当前Bean的依赖Bean,同时也是触发对依赖Bean的创建和注入。在对Bean的属性进行依赖注入时,解析地过程也是一个递归的过程。这样根据依赖关系,一层一层地完成Bean的创建和注入,直到最后完成当前Bean的创建。有了这个顶层Bean的创建和对它的属性依赖注入的完成,意味着和当前Bean相关的整个依赖链的注入也完成了。
在Bean创建和依赖注入完成以后,在IoC容器中建立起一系列依靠依赖关系联系联系起来的Bean,这个Bean已经不是简单的Java对象了。该Bean系列以及Bean之间的依赖关系建立完成以后,通过IoC容器的相关接口方法,就可以非常方便地供上层应用使用了。
0 0
- Spring源码分析----IOC依赖注入
- 深入研究Spring-IoC:源码分析依赖注入
- Spring源码学习-4.IoC.依赖注入
- Spring IOC依赖注入的过程分析
- Spring依赖注入源码分析
- Spring -- 依赖注入源码分析
- Spring源码学习IOC(5):IOC容器的依赖注入
- spring ioc依赖注入
- spring IOC依赖注入
- spring ioc 依赖注入
- Spring IOC 依赖注入
- Spring IoC依赖注入
- Spring-IoC依赖注入
- Spring源码分析之ioc注入
- 【Spring】Spring的IOC(控制反转)/DI(依赖注入)原理(三):Spring启动加载配置文件源码分析
- Spring IOC源码详解之容器依赖注入
- Spring:源码解读(IOC容器的依赖注入)
- Spring IOC容器的依赖注入(源码角度)
- MySQL_与MyEclipse进行集成
- java.io.IOException: 系统找不到指定的路径
- IIS7如何实现访问HTTP跳转到HTTPS访问
- angular ui-bootstrap的Datepicker Popup组件问题总结
- suid sgid 和sbit权限设置
- Spring源码分析----IOC依赖注入
- linux下sctp socket发送延迟问题
- python进阶15:继承、多态和多重继承
- 如何使用HTML5新增标签(一)
- Ant将Jmeter的jtl文件转为html文件报“前言中不允许有内容”
- 用cocos2dx打包时出现“make.exe: *** No rule to make target ”的解决方法
- 34. Search for a Range
- 生产者与消费者 Java代码描述
- SSD编译的时候出现问题