Spring源码一(容器的基本实现3)

38次阅读

共计 4049 个字符,预计需要花费 11 分钟才能阅读完成。

前言:继续前一章,接下来解析 Bean 标签的的属性信息。
1. 解析当前 bean 标签的内容
当我们创建了 bean 信息的承载实例之后,便可以进行 bean 信息的各种属性的解析了,首先我们进入 parseBeanDefinitionAttributes 方法,parseBeanDefinitionAttributes 方法是对 element 所有元素属性进行解析:/**
* Apply the attributes of the given bean element to the given bean * definition.
* @param ele bean declaration element
* @param beanName bean name
* @param containingBean containing bean definition
* @return a bean definition initialized according to the bean element attributes
*/
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {

if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
error(“Old 1.x ‘singleton’ attribute in use – upgrade to ‘scope’ declaration”, ele);
}
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
}
else if (containingBean != null) {
// Take default from containing bean in case of an inner bean definition.
bd.setScope(containingBean.getScope());
}

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

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

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

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

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));
}

if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
}

if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
bd.setInitMethodName(initMethodName);
}
else if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}

if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
bd.setDestroyMethodName(destroyMethodName);
}
else if (this.defaults.getDestroyMethod() != null) {
bd.setDestroyMethodName(this.defaults.getDestroyMethod());
bd.setEnforceDestroyMethod(false);
}

if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}

return bd;
}

通过以上代码我们可以发现,在 1.0 版本会有一个 singleton 不过呢,这个很快就被取代掉了,使用的话会提示错误信息,在新的版本里,我们使用了 scpoe=“singleton”作为一个新的使用方式,我们都知道在 spring 中,所创建的 bean 都被认为默认认为是单例的,并且通过 scope 这个关键字,即 scope=”singleton”。另外 scope 还有 prototype、request、session、global session 作用域。scope=”prototype” 多例。scope 就是一个作用域,如果有不太理解的话,可以参照一下:Spring scope 作用域详解。在这里只是看了一下 scope 标签的解析,那么肯定还会有很多的属性,我们用或者没有用过,但是就不做讲解了,我们知道 spring 是如何去做的就好了。
2. 解析 bean 中的元数据,meta 中的内容
例如:
<bean id=”car” class=”test.CarFactoryBean”>
<meta key = “key” value = “values”>
</bean>
通常我们通过配置文件使用 spring 的时候,我们会用到 meta 这个标签,这个标签中门会配置上,key,和 value 这两个属性,
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
Element metaElement = (Element) node;
String key = metaElement.getAttribute(KEY_ATTRIBUTE);
String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
attribute.setSource(extractSource(metaElement));
attributeAccessor.addMetadataAttribute(attribute);
}
}
}

通过代码,我们可以发现,spring 通过解析得到的 Element 树对象去得到子节点,然后便利子节点,并且取得 meta 元素的 key 值和 value 的知值,然后将其存储在 attributeAccessor 中。由此推测,其他的子集标签也会是通过这种方式去加载,并且这也符合我们的预期。
n

正文完
 0