加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

一、从 BeanDefinitionParserDelegate 解析xml bean元素,查看be

发布时间:2020-12-16 06:30:45 所属栏目:百科 来源:网络整理
导读:今天看了一下 BeanDefinitionParserDelegate 这个类,这个类是用来解析spring的xml配置文件中的bean的委托类,通过分析这个类,可以给 bean 的属性合理的值。 对于 bean 属性的解析,大部分是在 parseBeanDefinitionAttributes 方法执行,下为方法的定义: p

今天看了一下 BeanDefinitionParserDelegate 这个类,这个类是用来解析spring的xml配置文件中的bean的委托类,通过分析这个类,可以给 bean 的属性合理的值。

对于 bean 属性的解析,大部分是在 parseBeanDefinitionAttributes 方法执行,下为方法的定义:

public AbstractBeanDefinition parseBeanDefinitionAttributes(org.w3c.dom.Element ele,java.lang.String beanName,BeanDefinition containingBean,AbstractBeanDefinition bd)


首先是id和name属性,这个貌似没有过多的限制;如果id没有定义,会使用name的第一个值;然后name可以使用多值,中间以“,; ”(逗号、分号、空格)分割。id和name的解析在 parseBeanDefinitionElement 方法中,代码定义如下:

		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		List<String> aliases = new ArrayList<String>();
		if (StringUtils.hasLength(nameAttr)) {
                        // 这个 MULTI_VALUE_ATTRIBUTE_DELIMITERS = ",; "
                       String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr,MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
 		}

		 String beanName = id;
		 // 没有id,但是有name
		if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
			 // 使用name中的第一个
			 beanName = aliases.remove(0);
			 if (logger.isDebugEnabled()) {
 				logger.debug("No XML 'id' specified - using '" + beanName +
                         "' as bean name and " + aliases + " as aliases");
			}
		 }
	...
 
 
 

然后是class和parent,这两个属性在parseBeanDefinitionElement方法中:

		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			// class 因为要使用反射调用,所以,进行了去 空格 的处理操作
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}

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

			parseBeanDefinitionAttributes(ele,beanName,containingBean,bd);
			// description
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele,DESCRIPTION_ELEMENT));
                        ...
对于description,这是一个子标签,加注释用的,不过在国内都喜欢在标签上使用<!-- xx -->这种形式。

最后就是最重要的,parseBeanDefinitionAttributes方法中定义了大部分属性,下面进行一个一个的分析:

1. scope、singleton

		if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
			// Spring 2.x "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.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ?
					BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
		}
		else if (containingBean != null) {
			// Take default from containing bean in case of an inner bean definition.
			bd.setScope(containingBean.getScope());
		}

第一个if,如果存在 scope 属性的同时,还存在 singleton属性,就会报错;

第二个if,是建立在没有scope属性的前提上的,可以理解为:singleton == true?scope = singleton : scope = prototype;

第三个if,如果含有内部 bean ,则使用内部bean 的scope (此处待验证);

2. abstract

		if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
			bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
		}

true 或者 false ;

3. lazy-init

		String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
		if (DEFAULT_VALUE.equals(lazyInit)) {
			lazyInit = this.defaults.getLazyInit();
		}
		bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

默认值为default,如果为 default,会被转为 false,所以配置时,default == false;

4. autowire

		String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
		bd.setAutowireMode(getAutowireMode(autowire));

默认为 default,得到后在getAutowireMode方法进行处理,返回值为int,getAutowireMode代码如下:
		String att = attValue;
		if (DEFAULT_VALUE.equals(att)) {
			att = this.defaults.getAutowire(); // att 被赋值为 no
		}
		int autowire = AbstractBeanDefinition.AUTOWIRE_NO; // 0
		if (AUTOWIRE_BY_NAME_VALUE.equals(att)) { // byName
			autowire = AbstractBeanDefinition.AUTOWIRE_BY_NAME; // 1
		}
		else if (AUTOWIRE_BY_TYPE_VALUE.equals(att)) { // byType
			autowire = AbstractBeanDefinition.AUTOWIRE_BY_TYPE; // 2
		}
		else if (AUTOWIRE_CONSTRUCTOR_VALUE.equals(att)) { // constructor
			autowire = AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR; // 3
		}
		else if (AUTOWIRE_AUTODETECT_VALUE.equals(att)) { // autodetect
			autowire = AbstractBeanDefinition.<del>AUTOWIRE_AUTODETECT</del>; // 4
		}
 		// Else leave default value.
		return autowire;

可以看出,default 在起始被 更改 为 no,然后才进行别的处理,而 no 返回 0... 所以default == no;

5. dependency-check (这个属性貌似在3.0里边有所改变)

		String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
		bd.setDependencyCheck(getDependencyCheck(dependencyCheck));

这个在得到值之后,也是在getDependencyCheck方法中单独处理,返回的也是int值代表:

	public int getDependencyCheck(String attValue) {
		String att = attValue; // 默认attValue 是 "" 
		if (DEFAULT_VALUE.equals(att)) {// default
			att = this.defaults.getDependencyCheck(); // att == ""
		}
		if (DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE.equals(att)) {// all
			return AbstractBeanDefinition.DEPENDENCY_CHECK_ALL; // 3
		}
		else if (DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE.equals(att)) { // objects
			return AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS; // 1
		}
		else if (DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE.equals(att)) { // simple
			return AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE;// 2
		}
		else {
			return AbstractBeanDefinition.DEPENDENCY_CHECK_NONE; // 0
		}
	}

6. depends-on

<strong>		</strong>if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
			String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
			bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn,MULTI_VALUE_ATTRIBUTE_DELIMITERS));
		}

依赖关系,通过代码就可以看出来,这个的值,在spring内部切割的时候,使用MULTI_VALUE_ATTRIBUTE_DELIMITERS切割,而MULTI_VALUE_ATTRIBUTE_DELIMITERS的值是“,; ”(逗号、分号、空格);

7. autowire-candidate

		String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
		if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
			String candidatePattern = this.defaults.getAutowireCandidates();
			if (candidatePattern != null) {
				String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
				bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns,beanName));
			}
		}
		else {
			bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
		}

默认是default,用于指定自动装配时会不会考虑该bean,取值为 true/false;

8.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读