今天看了一下 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.