springロードbeanプロセスのソースコードの簡易解剖


この文章は主にbeanにロードする過程を話します。実はIOCです。控えめです。
大切なものを全部取り出しました。一歩下を見ると、springがbean.xmlに入るという原理が分かります。
候杰のMFCのような感じがします。
観覧ルール
次のコードを表します。
最近上で呼び出されるコードの詳細を表示します。





public class XmlBeanFactory extends DefaultListableBeanFactory {

        //    bean   , this        ,         bean ,       this         bean,      。  bean        XmlBeanFactory  (   DefaultListableBeanFactory)。 

	private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

	public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {

		super(parentBeanFactory);
                //  xml  
		this.reader.loadBeanDefinitions(resource); //  ->
	}
}

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
     //  
     public int loadBeanDefinitions(Resource resource) throws BeansException {

		InputStream is = null;

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

		factory.setValidating(this.validating);

		DocumentBuilder docBuilder = factory.newDocumentBuilder();

		docBuilder.setErrorHandler(this.errorHandler);

		if (this.entityResolver != null) {
		    docBuilder.setEntityResolver(this.entityResolver);
		}
		is = resource.getInputStream();
// Xerces  xml,  dom
		Document doc = docBuilder.parse(is);
//registerBeanDefinitions  dom
		return registerBeanDefinitions(doc, resource); //  

	}

//  
        public int registerBeanDefinitions(Document doc, Resource resource) throws BeansException {

		XmlBeanDefinitionParser parser = (XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass);
//  parserClass    DefaultXmlBeanDefinitionParser.class
		return parser.registerBeanDefinitions(this, doc, resource); //  ->

	}

}

public class DefaultXmlBeanDefinitionParser implements XmlBeanDefinitionParser {
//    bean.xml           ,          
       

	public static final String AUTOWIRE_BY_NAME_VALUE = "byName";
	public static final String AUTOWIRE_BY_TYPE_VALUE = "byType";
	public static final String DEFAULT_LAZY_INIT_ATTRIBUTE = "default-lazy-init";
	public static final String DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE = "default-dependency-check";
	public static final String DEFAULT_AUTOWIRE_ATTRIBUTE = "default-autowire";
	public static final String NAME_ATTRIBUTE = "name";
	public static final String ALIAS_ATTRIBUTE = "alias";
	public static final String BEAN_ELEMENT = "bean";
	public static final String ID_ATTRIBUTE = "id";
	public static final String PARENT_ATTRIBUTE = "parent";
	public static final String CLASS_ATTRIBUTE = "class";
	public static final String SINGLETON_ATTRIBUTE = "singleton";
	public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
	public static final String AUTOWIRE_ATTRIBUTE = "autowire";
	//...
   //  
   public int registerBeanDefinitions(BeanDefinitionReader reader, Document doc, Resource resource) throws BeanDefinitionStoreException {

		this.beanDefinitionReader = reader;
		this.resource = resource;;
		Element root = doc.getDocumentElement();
		//...

//          bean
		int beanDefinitionCount = parseBeanDefinitions(root);//  ->
//  beanDefinitionCount          <bean></bean>
		
//...
		return beanDefinitionCount;
	}

protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException {
//Xerces     <bean>  
		NodeList nl = root.getChildNodes();
		int beanDefinitionCounter = 0;
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (node instanceof Element) {
				Element ele = (Element) node;
				if // ...
//..
				else if (BEAN_ELEMENT.equals(node.getNodeName())) {//     ,    bean
					beanDefinitionCounter++;
//    ,     。1.  bean  BeanDefinitionHolder
					BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele);//   1.->
//2.  XmlBeanFactory   
					BeanDefinitionReaderUtils.registerBeanDefinition(
							bdHolder, this.beanDefinitionReader.getBeanFactory()); //   2. ->
				}
			}
		}
		return beanDefinitionCounter;
	}

//  1.   ,      ,     bean,      
protected BeanDefinitionHolder parseBeanDefinitionElement(Element ele) throws BeanDefinitionStoreException {
		//...
                //              bean      parseBeanDefinitionElement   。  spring bean   BeanDefinition   BeanDefinition    BeanDefinitionHolder 

		BeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName);//  

//...
		return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
	}

//   ,       ,  <bean> attribute  。
  protected BeanDefinition parseBeanDefinitionElement(Element ele, String beanName) throws BeanDefinitionStoreException {
		try {
                        //    <bean>  <property>,       。
			MutablePropertyValues pvs = parsePropertyElements(ele, beanName);
                        // BeanDefinition   AbstractBeanDefinition 
			AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
					className, parent, cargs, pvs, this.beanDefinitionReader.getBeanClassLoader());
			//...		
			return bd;
		}
		catch (/*...*/)
                   //...

		}
	}


}
//bean        。。。。


//  2.       ,    ,              。
public class BeanDefinitionReaderUtils {
  public static void registerBeanDefinition(
			BeanDefinitionHolder bdHolder, BeanDefinitionRegistry beanFactory) throws BeansException {

		
//beanFactory  XmlBeanFactory,        DefaultListableBeanFactory   registerBeanDefinition


		beanFactory.registerBeanDefinition(bdHolder.getBeanName(), bdHolder.getBeanDefinition()); //  
//...
	}

}

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
    implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
  
	/** Whether to allow re-registration of a different definition with the same name */
	private boolean allowBeanDefinitionOverriding = true;

	/** Map of bean definition objects, keyed by bean name */
//      bean   ,    Map,       。
	private final Map beanDefinitionMap = new HashMap();
//  List    bean       ,        。
	/** List of bean definition names, in registration order */
	private final List beanDefinitionNames = new ArrayList();
  //  
  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
//...
  Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
		if (oldBeanDefinition != null) {
//  allowBeanDefinitionOverriding        bean.xml  bean            ,  allowBeanDefinitionOverriding   true,    。
			if (!this.allowBeanDefinitionOverriding) {
				throw new BeanDefinitionStoreException(...);
			}
			else {
				//...        bean      
			}
		}
		else {
                        //  List     bean  
			this.beanDefinitionNames.add(beanName);
		}
                // bean  map 。      。
		this.beanDefinitionMap.put(beanName, beanDefinition);
		
	}
//...

}
//  
実際にspringはbean.xmlを一つのmapに解析することです。
beanを得る方法については、もちろん皆さんも知っています。一番下の階に行くとmap.getです。
万流が終わりますね。。。。