锁定老帖子 主题:Spring源代码解析(一):IOC容器
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-06-28
另外包含property value对象的BeanWrapperImpl怎么和容器中需要依赖他的bean相绑定呢?,上述的代码好像没有讲述到BeanDefinition与BeanWrapper的关系...
|
|
返回顶楼 | |
发表时间:2007-06-28
bennyparlo 写道 不过对于上述的过程中也有问题.
就是说在org.springframework.beans.factory.xml.BeanDefinitonParserDelegate中 public void parsePropertyElement(Element ele, BeanDefinition bd) { String propertyName = ele.getAttribute(NAME_ATTRIBUTE); if (!StringUtils.hasLength(propertyName)) { error("Tag 'property' must have a 'name' attribute", ele); return; } this.parseState.push(new PropertyEntry(propertyName)); try { if (bd.getPropertyValues().contains(propertyName)) { error("Multiple 'property' definitions for property '" + propertyName + "'", ele); return; } Object val = parsePropertyValue(ele, bd, propertyName); PropertyValue pv = new PropertyValue(propertyName, val); parseMetaElements(ele, pv); pv.setSource(extractSource(ele)); bd.getPropertyValues().addPropertyValue(pv); } finally { this.parseState.pop(); } } 这里的property value只是个从xml中解析来的Element(字符流的封装),具体到了装配的时候,确可以被识别不同类型的对象(),这个包装的过程,在哪里实现的呢? 我想这里是处理对Property的依赖关系解析,比如如果是一个"bean ref",就会生成一个RunTimeReferenceBean,在代码里可以看到: public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) { String elementName = (propertyName != null) ? "<property> element for property '" + propertyName + "'" : "<constructor-arg> element"; //这里取得这个Element的子元素值 NodeList nl = ele.getChildNodes(); Element subElement = null; for (int i = 0; i < nl.getLength(); i++) { if (nl.item(i) instanceof Element) { Element candidateEle = (Element) nl.item(i); //下面是对取得的子元素作的具体处理,取得subElement if (DESCRIPTION_ELEMENT.equals(candidateEle.getTagName())) { // Keep going: we don't use this value for now. } else { // Child element is what we're looking for. if (subElement != null && !META_ELEMENT.equals(subElement.getTagName())) { error(elementName + " must not contain more than one sub-element", ele); } subElement = candidateEle; } } } boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE); boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE); if ((hasRefAttribute && hasValueAttribute) || ((hasRefAttribute || hasValueAttribute)) && subElement != null) { error(elementName + " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele); } //如果这里取得的subElement是Ref bean,生成一个RuntimeBeanReference持有这个bean的名字,但是并不持有ref bean对象。 if (hasRefAttribute) { String refName = ele.getAttribute(REF_ATTRIBUTE); if (!StringUtils.hasText(refName)) { error(elementName + " contains empty 'ref' attribute", ele); } RuntimeBeanReference ref = new RuntimeBeanReference(refName); ref.setSource(extractSource(ele)); return ref; } else if (hasValueAttribute) { return ele.getAttribute(VALUE_ATTRIBUTE); } if (subElement == null) { // Neither child element nor "ref" or "value" attribute found. error(elementName + " must specify a ref or value", ele); } //这里处理其他类型的属性,比如我们看到的List,Map,Set等等 return parsePropertySubElement(subElement, bd); } 在这里对定义的依赖关系已经在BeanDefinition里面持有了,但是还没有对依赖进行注入。看来依赖解析和具体的依赖注入Spring是分成了两个过程来做的。 |
|
返回顶楼 | |
发表时间:2007-06-28
bennyparlo 写道 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory中 /** * Central method of this class: creates a bean instance, * populates the bean instance, applies post-processors, etc. * <p>Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { // 初始化被依赖的bean实例 if (mbd.getDependsOn() != null) { for (int i = 0; i < mbd.getDependsOn().length; i++) { getBean(mbd.getDependsOn()[i]); } } if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "' with merged definition [" + mbd + "]"); } // 判断当前bean的对象是否已经存在 Class beanClass = resolveBeanClass(mbd, beanName); // Prepare method overrides. try { mbd.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } String errorMessage = null; try { // Instantiate the bean. errorMessage = "BeanPostProcessor before instantiation of bean failed"; // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. if (beanClass != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Object bean = applyBeanPostProcessorsBeforeInstantiation(beanClass, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); return bean; } } // Instantiate the bean. errorMessage = "Instantiation of bean failed"; BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { synchronized (getSingletonMutex()) { instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName); } } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. if (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingleton(beanName, bean); } // Initialize the bean instance. errorMessage = "Initialization of bean failed"; // 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 (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) { BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next(); if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor; if (!ibp.postProcessAfterInstantiation(bean, beanName)) { continueWithPropertyPopulation = false; break; } } } } if (continueWithPropertyPopulation) { populateBean(beanName, mbd, instanceWrapper); } Object originalBean = bean; bean = initializeBean(beanName, bean, mbd); if (!this.allowRawInjectionDespiteWrapping && originalBean != bean && mbd.isSingleton() && hasDependentBean(beanName)) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans " + getDependentBeans(beanName) + " in its raw version as part of a circular reference, " + "but has eventually been wrapped (for example as part of auto-proxy creation). " + "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, and also as dependent on specified "dependsOn" beans. registerDisposableBeanIfNecessary(beanName, originalBean, mbd); return bean; } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, errorMessage, ex); } } 没有找到这个createBean()是在什么时候别调用的 ..... ??? 有点奇怪 应该在loadBeanDefinition之后,但是没有找到调用它的地方...... |
|
返回顶楼 | |
发表时间:2007-06-28
这个createBean被getBean方法调用了
public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException中调用了这个方法 |
|
返回顶楼 | |
发表时间:2007-06-28
也就是说,当调用loadBeanDefinition后,或者说调用了BeanDefinitionRegistry.registerBeanDefinition()以后,所有的resource定义被封装成BeanDefiniton并且存放到beanDefinitionMap后,被客户端使用的时候,去做了这些个bean注入的操作.按我的理解,spring的ioc容器在启动的时候,加载资源定义,而bean依赖的被注入,还要等到具体被客户端使用的时候.
|
|
返回顶楼 | |
发表时间:2007-06-28
bennyparlo 写道 这个createBean被getBean方法调用了
public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException中调用了这个方法 看到了,谢谢!!! 在AbstractFactoryBean中: 在AbstractFactoryBean中的getBean调用createBean public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException { final String beanName = transformedBeanName(name); Object bean = null; ........ // 这里检查是不是在父工厂里这个bean BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { //这里调用父工厂的getBean return ((AbstractBeanFactory) parentBeanFactory).getBean(nameToLookup, requiredType, args); } else if (args == null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { throw new NoSuchBeanDefinitionException(beanName, "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments"); } } this.alreadyCreated.add(beanName); final RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false); checkMergedBeanDefinition(mergedBeanDefinition, beanName, args); //这里调用bean的创建过程,也是依赖注入的地方,依赖解析已经完成放在BeanDefinition里面了 if (mergedBeanDefinition.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { public Object getObject() throws BeansException { try { return createBean(beanName, mergedBeanDefinition, args); } ......... } 那看来bean的依赖注入是在第一次向容器请求bean的时候完成的,loadBeanDefinition只是把定义的bean和依赖解析了以后存到容器里。这个createBean和getBean要好好看看。 |
|
返回顶楼 | |
发表时间:2007-06-28
bennyparlo 写道 也就是说,当调用loadBeanDefinition后,或者说调用了BeanDefinitionRegistry.registerBeanDefinition()以后,所有的resource定义被封装成BeanDefiniton并且存放到beanDefinitionMap后,被客户端使用的时候,去做了这些个bean注入的操作.按我的理解,spring的ioc容器在启动的时候,加载资源定义,而bean依赖的被注入,还要等到具体被客户端使用的时候.
完全同意!所以loadBeanDefinition和createBean是两个不同的过程,一个由容器启动的时候触发,一个由客户程序请求服务的时候触发!那大致可以看到启动的时候只是定位 - 读入 - 解析 - 注册,而最后的依赖注入还是要等到客户第一次请求bean的时候触发,如果有的bean不被请求,就不会被依赖注入。 |
|
返回顶楼 | |
发表时间:2007-06-29
经过和bennyparlo同学的讨论和MSN,大致把IOC容器完成依赖注入的过程梳理了一遍。让我代笔结合源代码在下面给出分析,望大家多提意见!- 很多细节没法顾及到,慢慢来吧!先发一个广告 :)
我们大致可以看到Spring把loadBean和依赖注入分成两个基本的过程,一个是在启动容器的时候完成,建立起一系列BeanDefinition,这些定义里面同时都包含了对bean依赖关系的描述,不过这里并没有对bean进行实例化,真正实例化的时候是在客户通过容器使用这些bean的时候 - 也就是getbean的时候。这个时候IOC容器根据需要会建立起一系列bean的实例和完成依赖注入。所以下面我们会详细的分析这个依赖注入的过程。 |
|
返回顶楼 | |
发表时间:2007-06-30
我们大致可以看到Spring把loadBean和依赖注入分成两个基本的过程,一个是在启动容器的时候完成,建立起一系列 BeanDefinition,这些定义里面同时都包含了对bean依赖关系的描述,不过这里并没有对bean进行实例化,真正实例化的时候是在客户通过容器使用这些bean的时候 - 也就是getbean的时候。这个时候IOC容器根据需要会建立起一系列bean的实例和完成依赖注入。所以下面我们会详细的分析这个依赖注入的过程。
让我们先简单回顾IOC容器启动时候载入bean定义文件的过程,这个过程是通过BeanDefinitionReader来完成的,其中通过 loadBeanDefinition()来对定义文件进行解析和根据Spring定义的bean规则进行处理 - 事实上和Spring定义的bean规则相关的处理是在BeanDefinitionParserDelegate中完成的,完成这个处理需要得到用户定义的bean定义信息,这是在前面已经通过解析已经完成了的,这个处理过程的结果就是得到了一系列的BeanDefinition,这里不但包含了对 bean定义信息解析后的表示,同时还把和这个bean相关的依赖信息也保存了下来。那以后这些信息怎样被取得和被使用呢?在完成了这一系列的解析和处理之后,接着需要对对BeanFactoryRegistry的接口做一个回调,把这些BeanDefinition都放到一个HashMap - beanDefinitionMap里面,以后对这些信息的操作通过这个HashMap来完成。这样就完成了IOC启动过程中最重要的部分 - 依赖关系的解析,处理和建立,下面就是使用IOC容器的时候完成的依赖注入的行为。在AbstractBeanDefinition中我们看到有这些和依赖关系处理紧密相关的属性: public abstract class AbstractBeanDefinition extends AttributeAccessorSupport implements BeanDefinition { ....... private Object beanClass; ...... //这个属性持有的这个bean的依赖属性,比如各种property的定义信息 private MutablePropertyValues propertyValues; ...... } 很显然这些值都是在BeanDefinitionParserDelegate中设置的: public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { //这里得到定义的类的名字 - 通过属性Class String className = null; if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE); } ......... try { this.parseState.push(new BeanEntry(beanName)); //这里是生成BeanDefinition的地方,也是生成根据定义的class属性来生成bean JAVA对象的地方 //以前我们已经分析过了,这里生成一个BeanDefinition , 它里面已经持有了生成的bean Java对象。 AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition( parent, className, getReaderContext().getReader().getBeanClassLoader()); //下面是一系列对beandefinition的属性设置,依据是用户定义的bean定义信息,类似于用户定义的bean定义信息的读入 if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { // Spring 2.0 "scope" attribute bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error("Specify either 'scope' or 'singleton', not both", ele); } } else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { // Spring 1.x "singleton" attribute bd.setSingleton(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE))); } .......... parseMetaElements(ele, bd); parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); parseConstructorArgElements(ele, bd); //注意这里是对依赖关系,也就是bean对象属性的处理! parsePropertyElements(ele, bd); bd.setResourceDescription(getReaderContext().getResource().getDescription()); bd.setSource(extractSource(ele)); return bd; ................ } 在辅助类BeanDefinitionReaderUtils中对bean对象做了原始的创建: public static AbstractBeanDefinition createBeanDefinition( String parent, String className, ClassLoader classLoader) throws ClassNotFoundException { AbstractBeanDefinition bd = null; if (parent != null) { bd = new ChildBeanDefinition(parent); } else { bd = new RootBeanDefinition(); } //这里创建了bean的JAVA对象,同时在beandefinition中持有 if (className != null) { if (classLoader != null) { bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { bd.setBeanClassName(className); } } return bd; } 下面我们分析parsePropertyElements(ele, bd)看看那些属性依赖关系是怎样处理的: public void parsePropertyElements(Element beanEle, BeanDefinition bd) { //这里取得所有定义的属性定义 NodeList nl = beanEle.getChildNodes(); //很显然,需要一个一个的处理 for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element && DomUtils.nodeNameEquals(node, PROPERTY_ELEMENT)) { parsePropertyElement((Element) node, bd); } } public void parsePropertyElement(Element ele, BeanDefinition bd) { //这里得到属性定义的名字 String propertyName = ele.getAttribute(NAME_ATTRIBUTE); if (!StringUtils.hasLength(propertyName)) { error("Tag 'property' must have a 'name' attribute", ele); return; } this.parseState.push(new PropertyEntry(propertyName)); try { //判断是不是已经有重名的属性定义 if (bd.getPropertyValues().contains(propertyName)) { error("Multiple 'property' definitions for property '" + propertyName + "'", ele); return; } //这里根据属性的名字对属性的定义进行具体的解析,结果放在PropertyValue对象里面 //这里包含了对各种属性类型的解析,比如List,Map,Set,当然还有reference bean等等, //这个propertyValue是连接和表示各个bean之间依赖关系的桥梁 Object val = parsePropertyValue(ele, bd, propertyName); PropertyValue pv = new PropertyValue(propertyName, val); parseMetaElements(ele, pv); pv.setSource(extractSource(ele)); //最后把这个解析的结果,也就是生成的Property对象放到beanDefinition里面去 bd.getPropertyValues().addPropertyValue(pv); } finally { this.parseState.pop(); } } 我们看看具体的对各种属性定义的解析,在parsePropertyValue函数中: public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) { String elementName = (propertyName != null) ? "<property> element for property '" + propertyName + "'" : "<constructor-arg> element"; // Should only have one child element: ref, value, list, etc. //这里根据DOM取得需要分析的属性定义 NodeList nl = ele.getChildNodes(); Element subElement = null; for (int i = 0; i < nl.getLength(); i++) { if (nl.item(i) instanceof Element) { Element candidateEle = (Element) nl.item(i); if (DESCRIPTION_ELEMENT.equals(candidateEle.getTagName())) { // Keep going: we don't use this value for now. } else { // Child element is what we're looking for. if (subElement != null && !META_ELEMENT.equals(subElement.getTagName())) { error(elementName + " must not contain more than one sub-element", ele); } subElement = candidateEle; } } } boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE); boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE); if ((hasRefAttribute && hasValueAttribute) || ((hasRefAttribute || hasValueAttribute)) && subElement != null) { error(elementName + " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele); } if (hasRefAttribute) { //这里是对ref属性的解析,称称一个RuntimeBeanReference对象, //这个RuntimeBeanReference很简单,只是保持beanName,toParent,source三个属性信息,对记录依赖关系已经足够了 String refName = ele.getAttribute(REF_ATTRIBUTE); if (!StringUtils.hasText(refName)) { error(elementName + " contains empty 'ref' attribute", ele); } RuntimeBeanReference ref = new RuntimeBeanReference(refName); ref.setSource(extractSource(ele)); return ref; } else if (hasValueAttribute) { return ele.getAttribute(VALUE_ATTRIBUTE); } if (subElement == null) { // Neither child element nor "ref" or "value" attribute found. error(elementName + " must specify a ref or value", ele); } //这里对各种其他属性值进行处理,比如List,Map,Set等等 return parsePropertySubElement(subElement, bd); } 比如我们举个例子看看对List属性的解析,也是生成一个对应的List对象,里面记录了相关的定义信息, public List parseListElement(Element collectionEle, BeanDefinition bd) { String defaultTypeClassName = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE); NodeList nl = collectionEle.getChildNodes(); ManagedList list = new ManagedList(nl.getLength()); list.setSource(extractSource(collectionEle)); list.setMergeEnabled(parseMergeAttribute(collectionEle)); //这里对List的各个子属性进行处理,结果放到这个List,然后返回到beandefinition中以后可以使用。 for (int i = 0; i < nl.getLength(); i++) { if (nl.item(i) instanceof Element) { Element ele = (Element) nl.item(i); list.add(parsePropertySubElement(ele, bd, defaultTypeClassName)); } } return list; } 这样就把相应的属性对象都解析完,而且都放到了beandefinition中去,这个beandefinition是以后容器进行依赖注入和依赖管理的最主要的数据结构。 |
|
返回顶楼 | |
发表时间:2007-06-30
有了上面的准备,我们可以看看依赖关系是怎样被注入的,我们知道IOC容器在loadBeanDefinition的时候只是完成了bean定义的解析和向IOC容器的注册,这个时候并没有对依赖的实现注入,具体的注入过程是在客户程序向IOC容器要求bean的时候完成的,具体的过程我们在代码中可以看到 - 在AbstractFactoryBean中:
public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException { final String beanName = transformedBeanName(name); Object bean = null; // Eagerly check singleton cache for manually registered singletons. // 这里先从缓存中去取,处理那些已经被创建过的单件模式的bean,对这种bean的请求不需要重复的去创建 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null) { if (isSingletonCurrentlyInCreation(beanName)) { ....... } else { ....... } if (containsBeanDefinition(beanName)) { RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false); bean = getObjectForBeanInstance(sharedInstance, name, mergedBeanDefinition); } else { bean = getObjectForBeanInstance(sharedInstance, name, null); } } else { // Fail if we're already creating this singleton instance: // We're assumably within a circular reference. if (isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. //这里检查是否能在当前的工厂中取到我们需要的bean,如果在当前的工厂中取不到,则到父工厂取,如果一直取不到 //那就顺着工厂链一直向上查找 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); // 这里调用父工厂的getbean取需要的bean // 这里有一个迭代,在父工厂中也会重复这么一个getbean的过程。 if (parentBeanFactory instanceof AbstractBeanFactory) { // Delegation to parent with args only possible for AbstractBeanFactory. return ((AbstractBeanFactory) parentBeanFactory).getBean(nameToLookup, requiredType, args); } else if (args == null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { throw new NoSuchBeanDefinitionException(beanName, "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments"); } } //把这个已经被要求过的bean记录下来,因为第一次要求bean的时候往往就是依赖被容器对bean进行注入的时候。 this.alreadyCreated.add(beanName); final RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false); checkMergedBeanDefinition(mergedBeanDefinition, beanName, args); // Create bean instance. //这里是根据beandefinition来创建bean和完成依赖注入的地方。 if (mergedBeanDefinition.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { public Object getObject() throws BeansException { try { //注意这个createBean,是创建bean同时完成依赖注入的地方。 return createBean(beanName, mergedBeanDefinition, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, mergedBeanDefinition); } //这里是处理prototype类型的bean请求的地方 else if (mergedBeanDefinition.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); //每次请求,直接通过createBean来创建 prototypeInstance = createBean(beanName, mergedBeanDefinition, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, mergedBeanDefinition); } ........ return bean; } 具体的bean创建过程和依赖关系的注入在createBean中,这个方法在 AbstractAutowireCapableBeanFactory中给出了实现: protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition, Object[] args) throws BeanCreationException { // Guarantee initialization of beans that the current one depends on. // 这里对取得当前bean的所有依赖bean,确定能够取得这些已经被确定的bean,如果没有被创建,那么这个createBean会被这些IOC // getbean时创建这些bean if (mergedBeanDefinition.getDependsOn() != null) { for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) { getBean(mergedBeanDefinition.getDependsOn()[i]); } } ........ // 这里是实例化bean对象的地方,注意这个BeanWrapper类,是对bean操作的主要封装类 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mergedBeanDefinition, args); } Object bean = instanceWrapper.getWrappedInstance(); ...... //这个populate方法,是对已经创建的bean实例进行依赖注入的地方,会使用到在loadBeanDefinition的时候得到的那些propertyValue来对bean进行注入。 if (continueWithPropertyPopulation) { populateBean(beanName, mergedBeanDefinition, instanceWrapper); } //这里完成客户自定义的对bean的一些初始化动作 Object originalBean = bean; bean = initializeBean(beanName, bean, mergedBeanDefinition); // Register bean as disposable, and also as dependent on specified "dependsOn" beans. registerDisposableBeanIfNecessary(beanName, originalBean, mergedBeanDefinition); return bean; } ......... } |
|
返回顶楼 | |