spring默认标签的解析

(1)首先委托BeanDefinitionDelegate类的parseBeanDefinitionElement方法进行元素解析,返回BeanDefinitionHolder类型的实例dbHolder,经过这个方法后,dbHolder实例已经包含我们配置文件中配置的各种属性了,例如class,name,id,alias之类的属性.
(2)当返回的dbHolder不为空的情况下若存在默认标签的子节点下再有自定义属性,还需要再次对自定义标签进行解析.
(3)解析完成之后,需要对解析后的dbHolder进行注册,同样,注册操作委托给了BeanDefinitionReaderUtils的registerBeanDefinition方法.
(4)最后发出响应时间,通知相关的监听器,这个bean已经加载完成了.

(1)如果name属性值不为空,就以逗号来分割它,并存放在ArrayList中.
如果有id就把id作为beanName,否则就把aliases数组的第一个元素作为beanName,如果还为空就使用内部规则生成一个beanName(类名#0,1,2,3…)

(2)对自定义标签的解析的过程如下:

public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean){
	this.parseState.push(new BeanEntry(beanName));
	String className = null;
	// 解析class属性
	if (ele.hasAttribute(CLASS_ATTRIBUTE)){
		className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
	}
	try {
		String parent = null;
		//解析parent属性
		if (ele.hasAttribute(PARENT_ATTRIBUTE)){
			parent = ele.getAttribute(PARENT_ATTRIBUTE);
		}
		//1.创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition
		AbstractBeanDefinition bd = createBeanDefinition(className, parent);
		//2.硬编码解析默认bean的各种属性
		parseBeanDefinitionAttribute(ele, beanName, containingBean, db);
		//3.解析元数据
		parseMetaElements(ele, bd);
		//4.解析lookup-method属性
		parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
		//5.解析replaced-method属性
		parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
		//6.解析构造函数参数
		parseConstructorArgElements(ele, bd);
		//7.解析property子元素
		parsePropertyElements(ele, bd);
		//8解析qualifier子元素
		parseQualifierElements(ele, bd);
		
		bd.setResource(this, readerContext.getResource());
		bd.setSource(extractSource(ele));

        return bd;
	}
}

1. 创建用于属性继承的BeanDefinition

BeanDefinition是一个接口,在spring中存在三种实现:RootBeanDefinition, ChildBeanDefinition, 以及GenericBeanDefinition.
三种实现都继承了AbstractBeanDefinition,其中BeanDefinition是配置文件元素标签在容器中的内部表示形式.
标签拥有class,scope,lazy-init等配置属性,BeanDefinition则提供了相应的beanClass, scope, lazyInit属性,BeanDefinition和中的属性是一一对应的.

在配置文件中可以定义父和子,父用RootBeanDefinition表示,而子用ChildBeanDefinition表示,而没有父的子就使用RootBeanDefinition表示.AbstractBeanDefinition对两者共同的类信息进行抽象.

Spring通过BeanDefinition将配置文件中的配置信息转换为容器的内部表示,并将这些BeanDefinition注册到BeanDefinitionRegistry中.Spring容器的BeanDefinitionRegistry就像是Spring配置信息的内存数据库,主要是以map的形式保存,后续操作直接从BeanDefinitionRegistry中读取配置信息.

BeanDefinition在被创建的时候是如何实现实例的唯一性的:

BeanDefinitionReaderUtils.java
public static AbstractBeanDefinition createBeanDefinition(String parentName,String className, ClassLoader classLoader) throws ClassNotFoundException{

    GenericBeanDefinition db = new GenericBeanDefinition();
    //parentName 可能为空
    bd.setParentName(parentName);
    if (className != null){
        if (classLoader != null){
            //如果classLoader不为空,则使用和传入的classLoader同一虚拟机加载类对象,否则只是记录className
            bd.setBeanClass(ClassUtils.forName(className, classLoader));
        }else{
            bd.setBeanClassName(className);
        }
    }
    return bd;
}

2. 解析Bean元素的各种属性

创建完BeanDefinition属性之后,就需要对bean元素的各种属性进行解析了.

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd){

    //解析scope属性
    if (ele.hasAttribute(SCOPE_ATTRIBUTE)){
        //Spring 2.x "scope" attribute
        bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
        if (ele.hasAttribute(SINGLETON_ATTRIBUTE)){
            //scope 与singleton两个属性只能指定其中之一,不可以同时出现,否则Spring将会报异常
            error("Specify either 'scope' or 'singleton', not both", ele);
        }
    }
    //解析singleton属性
    else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)){
        // Spring 1.x "singleton" attribute
        bd.setScope(TRUE_VAULE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE))?BeanDefinition.SCOPE_SINGLETON : BeanDefintion.SCOPE_PROTOTYPES);
    }
    else if (containingBean != null){
        // Take default from containing bean in case of inner bean definition
        // 在嵌入beanDefinition情况下且没有单独指定scope属性则使用父类默认的属性
        bd.setScope(containingBean.getScope());
    }
    //解析abstract属性
    if(ele.hasAttribute(ABSTRACT_ATTRIBUTE)){
        bd.setAbstract(TRUE_VALUE.equels(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
    }
    //解析lazy-init属性
    String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
    if (DEFAULT_VALUE.quals(lazyInit)){
        lazyInit = this.defaults.getLazyInit();
    }
    //若没有设置或设置成其他字符都会被设置为false
    bd.setLazyInit(TRUE_VALEU.equals(lazyInit);

    //解析autowire属性
    String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
    bd.setAutowireMode(getAutowireMode(autowire));

    //解析dependency-check属性
    String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
    bd.setDependencyCheck(getDependencyCheck(dependencyCheck));

    //解析depends-on属性
    if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)){
        String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
        bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, NULTI_VALUE_ATTRIBUTE_DELIMITERS));
    }

    //解析autowire-candidate属性
    String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
    if ("".equals(autowireCandidate)|| DEFAULT_VALUE.equals(autowireCandidate)){
        String candidatePattern = this.default.getAutowireCandates();
        if (candidatePattern != null){
            String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
            bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
        }
    }
    else {
        bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
    }

    //解析private属性
    if (ele.hasAttribute(PRIVATE_ATTRIBUTE)){
        bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
    }

    //解析init_method属性
    if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)){
        String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
        if (!"".equals(initMethodName)){
            bd.setInitMethodName(initMethodName);
        }
    }
    else {
        if (this.defaults.getInitMethod()!=null){
            bd.setInitMethodName(this.defaults.getInitMethos());
            bd.setEnforceInitMethod(false);
        }
    }

    //解析destroy-methos属性
    if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)){
        String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
        if (!"".equals(destroyMethodName)){
            bd.setDestroyMethodName(destroyMethodName);
        }
    }
    else{
        if (this.default.getDestroyMethod() != null){
            bd.setDstroyMethosName(this.default.getDestoryMethod);
            bd.setEnforceDestroyMethod(false);
        }
    }

    //解析factory-method解析
    if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)){
        bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
    }

    return bd;

}

3.解析子元素meta

<bean id ="myTestBean" class="bean.MyTestBean">
    <meta key="testStr" value="aaaaa">
</bean>

## mate元素的解析代码
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor){
    //获取当前节点的所有子元素
    NodeList nl = ele.getChildNodes();
    for (int i =0; i < nl.getLength(); i++){
        Node node = nl.item(i);
        //提取meta
        if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)){
            Element metaElement = (Element)node;
            String key = metaElement.getAttribute(KET_ATTRIBUTE);
            String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
            //使用key, value构造BeanMetadataAttribute
            BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
            attribute.setSource(extractSource(metaElement));
            //记录信息
            attributeAccessor.addMetadataAttribute(attribute);
        }
    }
}

还有其他子元素的解析,这里就不细说了

上一篇:浮点型变量/常量


下一篇:JS------获取一个时间区间的所有天