一歩ずつspring(四)——IocのBeanの注入を勉強します.


まず、Application ContectはResource Loaderを拡張しています.XmlBenFactoryとは異なり、コンテナが起動する時に、Application ContectにResourceに入る必要はなく、Springのリソースファイル名を入力するだけで、Application Contextは自動的にリソースファイル名に対応するResourceをロードします.また、複数のリソースファイルを同時に配置してApplication Contectに送ることができます.
    
   容器起動時にビーンの注入プロセスを開始しました.具体的に詳細な注入過程は、ネット上に山ほどあります.Javaeyeの中の比較的古典的なIOC注入分析を紹介します.
 
http://www.iteye.com/wiki/Spring-source/1226-Springソースコード解析(一):IOC容器
  
   ここでは、主に資源ファイルの中での属性Beanの詳細な解析過程を分析します.
   springにおけるxmlリソースの解析は、主にXml BeanDefinitionReaderによって行われ、このクラスは、Appplication Contect容器の起動時に初期化される.解析の詳細なプロセスは、BeanDefinitionParsDelegateエージェントが完了したものです.
  
  BeanDefinitionParseBeanDefinitionElementメソッド:
 
 

       /**
	 * Parse the bean definition itself, without regard to name or aliases. May return
	 * <code>null</code> if problems occured during the parse of the bean definition.
	 */
	public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, BeanDefinition containingBean) {
       /*
        * parserState    ,      ParseState.Entry     ,  ,   String   beanName    ,\
        *    beanName   Entry  
        */
		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}

		try {
			String parent = null;
			if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
				parent = ele.getAttribute(PARENT_ATTRIBUTE);
			}
			/*
			 *     new  BeanDefinition  ,    BeanDefinition className  parent   
			 */
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);

			/*
			 *  "<id="" name="" scope="" ..>"        ,    Bean       、
			 *       、          ,          BeanDefinition  
			 */
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			//  Bean "<description ../>"  
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
            
			parseMetaElements(ele, bd);
			//  "<look-up ..>"     ,            Beandefinition methoOverrides   
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			//  "<replace ..>"     ,            Beandefinition methoOverrides   
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
            
			/*
			 * spring  Ioc       :      、set         ,    
			 *          
			 */
			
			//        
			parseConstructorArgElements(ele, bd);
			//set       (       )
			parsePropertyElements(ele, bd);
			parseQualifierElements(ele, bd);

			bd.setResource(this.readerContext.getResource());
			bd.setSource(extractSource(ele));

			return bd;
		}
		catch (ClassNotFoundException ex) {
			error("Bean class [" + className + "] not found", ele, ex);
		}
		catch (NoClassDefFoundError err) {
			error("Class that bean class [" + className + "] depends on not found", ele, err);
		}
		catch (Throwable ex) {
			error("Unexpected failure during bean definition parsing", ele, ex);
		}
		finally {
			this.parseState.pop();
		}

		return null;
	}
以下、set注入形式の解析処理を分析します.この処理はパーサービーンDefinitionElement方法で行われます.具体的には以下の通りです.
/**
	 * Parse property sub-elements of the given bean element.
	 */
	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);
			}
		}
	}
 
  ParsePropertyElement(Element ele、BeanDefinition bd)の方法コードは以下の通りです.
 

   /**
	 * Parse a property element.
	 */
	public void parsePropertyElement(Element ele, BeanDefinition bd) {
		//  <proiperty name=..> name   
		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 {
			//   BeanDefinition          name      ,     
			if (bd.getPropertyValues().contains(propertyName)) {
				error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
				return;
			}
			//   propertyName    ,         string,    List  ,    BeanDefinition     Bean(  "ref="     )
			Object val = parsePropertyValue(ele, bd, propertyName);
			//   PropertyValue
			PropertyValue pv = new PropertyValue(propertyName, val);
			//      
			parseMetaElements(ele, pv);
			pv.setSource(extractSource(ele));
			/*
			 *       PropertyValue   BeanDefinition PropertyValues ,
			 *      : 1.     ,   BeanDefinition   Bean ,     Bean    
			 *            2.    BeanDefiniton      propertyName
			 */
			bd.getPropertyValues().addPropertyValue(pv);
		}
		finally {
			this.parseState.pop();
		}
	}

             :what how why.   ,       、    spring   ,                why。   ,       。
        ,          ,       ,              java  ,                   。