(精典) Spring配备中id和name属性的值能相等吗?(讨论)
(精典) Spring配置中id和name属性的值能相等吗?(讨论)
最近,我在使用Spring的时候,出现这样一个问题,令我感到迷惑,各位如果有时间,请帮忙研究下,帮小弟我解决这个问题。问题大致是这样的:
以前,在网上看到很多文章,大致意思是说在Spring的配置文件中,id的值不允许相同,但是name的值是可以相同的,并且,如果name相同,在通过getBean获得bean对象实例时,后配置的bean将会覆盖先前配置中name值相同的bean,比如说这篇博文:
http://blog.csdn.net/dagouaofei/archive/2009/07/01/4313431.aspx
但是,在我测试时(多个bean的name属性配置成相同的值),居然出现了异常,异常大致信息是说“beianName 已经在当前文件中使用了”。
这种现象和网上说的不符啊,于是,我看了下源码,真的不是网上说的那么回事,源码我贴出来,各位参考下:
BeanDefinitionParserDelegate类为配置文件解析代理类,以下为此类中的两个方法:
checkNameUniqueness方法内容:
从源码中可以看出,配置文件中所有Bean的name的值不仅不能相同,而且bean的id的值和bean的name的值也不能相同,包括bean的别名也一样。这是怎么回事?难道是我理解错了?还是spring版本太低了(我采用的是2.0的)?还是网上说的有误?(可是这样的文章很多,都是那个意思,我想有误的可能性很少吧)。所以,如果哪位知道的,请留言告诉我,不胜感激。
最近,我在使用Spring的时候,出现这样一个问题,令我感到迷惑,各位如果有时间,请帮忙研究下,帮小弟我解决这个问题。问题大致是这样的:
以前,在网上看到很多文章,大致意思是说在Spring的配置文件中,id的值不允许相同,但是name的值是可以相同的,并且,如果name相同,在通过getBean获得bean对象实例时,后配置的bean将会覆盖先前配置中name值相同的bean,比如说这篇博文:
http://blog.csdn.net/dagouaofei/archive/2009/07/01/4313431.aspx
但是,在我测试时(多个bean的name属性配置成相同的值),居然出现了异常,异常大致信息是说“beianName 已经在当前文件中使用了”。
这种现象和网上说的不符啊,于是,我看了下源码,真的不是网上说的那么回事,源码我贴出来,各位参考下:
BeanDefinitionParserDelegate类为配置文件解析代理类,以下为此类中的两个方法:
/** * Parses the supplied <code><bean></code> element. May return <code>null</code> * if there were errors during parse. Errors are reported to the * {@link org.springframework.beans.factory.parsing.ProblemReporter}. */ public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { String id = ele.getAttribute(ID_ATTRIBUTE); //获得Bean的id名 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); //获得Bean的name字符串 //拆分Bean的name字符串为多个Bean的name,然后存入List中 List aliases = new ArrayList(); if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } //将Bean的id名赋值给beanName 注:beanName和Bean的name不是同一个概念 String beanName = id; //如果bean的id为null或“”,则将Bean的name的List集合中第一个值赋值给BeanName if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = (String) aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } /* * 此处进行BeanName验 */ if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } ......
checkNameUniqueness方法内容:
/** * @description 此方法中的usedNames为一Set集合,所有的BeanName将存入此set中 * @param beanName * 需要验证的beanName * @param aliases bean的name的List集合 * @param beanElement */ private void checkNameUniqueness(String beanName, List aliases, Element beanElement) { String foundName = null; /* * 如果beanName不为空并且usedNames(set集合)中已经存在了此beanName,则赋值给foundName */ if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) { foundName = beanName; } this.usedNames.add(beanName); //将当前beanName添加的集合中 if (foundName == null) { /* * 找出usedNames集合中和aliases结合中第一个相等的元素,并赋值给foundName */ foundName = (String) CollectionUtils.findFirstMatch(this.usedNames, aliases); } this.usedNames.addAll(aliases); //将bean的name集合(bean的所有别名)存入到usedNames中 //如果foundName不为空,则抛出当前beanName已经存在的异常 if (foundName != null) { getReaderContext().error("Bean name '" + foundName + "' is already used in this file.", beanElement); } }
从源码中可以看出,配置文件中所有Bean的name的值不仅不能相同,而且bean的id的值和bean的name的值也不能相同,包括bean的别名也一样。这是怎么回事?难道是我理解错了?还是spring版本太低了(我采用的是2.0的)?还是网上说的有误?(可是这样的文章很多,都是那个意思,我想有误的可能性很少吧)。所以,如果哪位知道的,请留言告诉我,不胜感激。
1 楼
yfnok
2010-04-19
应该是版本问题——我猜