Spring之默认标签的解析(三) bean标签的解析及注册(2)BeanDefinition和其属性的解析
创建用于属性承载的BeanDefinition
- createBeanDefinition
protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
throws ClassNotFoundException {
return BeanDefinitionReaderUtils.createBeanDefinition(
parentName, className, this.readerContext.getBeanClassLoader());
}
- createBeanDefinition
*/
public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
bd.setBeanClassName(className);
}
}
return bd;
}
上文中我们看了函数parseBeanDefinitionElement,其中调用了上述方法createBeanDefinition,目的就是为了创建BeanDefinition,而BeanDefinition的作用,我们分析下:
首先BeanDefinition是一个接口,在 Spring 中存在三种实现: RootBeanDefinition、ChildBeanDefinition 以及 GenericBeanDefinition 三 种实现均继承了 AbstractBeanDefinition ,其中 BeanDefinition 是配置文件元素标签在容器中的内部表示形式 。 元素标签拥有 class、 scope、 lazy-init等配置属性, BeanDefinition则提供了相应的 beanClass、 scope、 lazyInit 属性, BeanDefinition和中的属性是一一对应的。 其中 RootBeanDefinition是最常用的实现类,它对应一般性的元素标签,GenericBeanDefinition 是自 2.5 版本以后新加入的 bean 文件配置属性定义类,是一站式服务类。
在配置文件中可以定义父和子,父用 RootBeanDefinition 表示,而子 用 ChildBeanDefinition 表示,而没有父的就使用 RootBeanDefinition表示。 AbstractBeanDefinition 对两者共同的类信息进行抽象。Spring通过 BeanDefinition将配置文件中的配置信息转换为容器的内部表示,并将这些 BeanDefinition 注册到BeanDefinitionRegistry 中。Spring容器的 BeanDefinitionRegistry就像是Spring配置信息的内存数据库,主要是以 map 的形式保存,后续操作直接从 BeanDefinitionRegistry 中读取配置信息 。
关系如图:
到此,我们就明白,要解析所有的属性,首先就是要创建用于承载属性的实例也就是创建beanDefinition类型的实例。
解析各种属性
创建完Bean的信息载体后,我们就可以逐步去完成bean信息的各种属性解析了,我们继续跟踪代码,首先就是parseBeanDefinitionAttributes方法
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
// 解析singleton属性
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
}
// 解析scope属性
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());
}
// 解析abstract属性
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
// 解析lazy-init属性
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (isDefaultValue(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
// 解析autowire属性
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
bd.setAutowireMode(getAutowireMode(autowire));
// 解析dependency-on属性
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
// 解析dependency-candidate属性
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if (isDefaultValue(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));
}
// 解析primary属性
if (ele.hasAttribute(PRIMARY_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);
bd.setInitMethodName(initMethodName);
}
else if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
// 解析destroy-method属性
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);
}
// 解析factory-method属性
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
// 解析destroy-bean属性
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}
return bd;
}
到这里,spring完成了对bean各属性的解析。有部分属性,大概都没有怎么用过,等有时间我们一起探讨这些常用或非常用的属性。接下来我们还是先了解流程,预知结果如何,那下回分解吧…