文章源自JAVA秀-https://www.javaxiu.com/19908.html
回顾:通过前面一章节的了解,我们基本上知道了applicationContext.xml文件的整体的反复的封装过程。在beanfactory篇-(十一)spring的核心过程一之bean描述信息的注册 这篇文章里面,有提到关键的一些代码,就是将bean描述信息注册到beanDefinitionMap中。但是中间有一步,我们直接就跳过去了,没有细致的进行追踪了解。本章节我们对该分支逻辑进行详细的了解。 文章源自JAVA秀-https://www.javaxiu.com/19908.html
文章源自JAVA秀-https://www.javaxiu.com/19908.html
1. bean标签解析过程的整体理解
在下面的代码中,我们知道代码行BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());是关键核心代码,主要是把bean描述信息注册到beanDefinitionMap中。文章源自JAVA秀-https://www.javaxiu.com/19908.html
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
//关键核心代码,把bean描述信息(也就是BeanDefinitionHolder对象)注册到beanDefinitionMap中。
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
然而本章节我们不关注bean描述信息的注册,而是关注bean描述信息的具体转换,也就是下面这行代码的过程。文章源自JAVA秀-https://www.javaxiu.com/19908.html
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
通过前面的一章节,我们知道了一个bean描述信息通过了一个漫长的解析过程,终于从下面的标签信息文章源自JAVA秀-https://www.javaxiu.com/19908.html
<bean id="userService" name="userService" class="com.minesoft.tutorial.service.UserServiceImpl"
scope="singleton"
autowire="byType"
abstract="false"
lazy-init="true"
factory-bean="userServiceXmlFactoryBean"
factory-method="createUserService"
/>
被解析封装成为了Element对象。那么Element对象,是如何被转换成为一个BeanDefinitionHolder对象的呢?下面我们跟踪代码,一步一步解开这个疑问。文章源自JAVA秀-https://www.javaxiu.com/19908.html
注意:不管是上面的一段bean标签信息,还是Element对象,还是BeanDefinitionHolder对象,本质上都是一个东西,那就是bean描述信息,只不过给人展现的形态不一样而已。这种抽象的思想,是一个开发者需要多加理解的。文章源自JAVA秀-https://www.javaxiu.com/19908.html
2. Element对象到BeanDefinitionHolder对象解析过程
[1] 首先将转换成为一个BeanDefinitionHolder对象的工作委托给delegate对象(BeanDefinitionParserDelegate)文章源自JAVA秀-https://www.javaxiu.com/19908.html
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//将转换工作整体委托给BeanDefinitionParserDelegate对象处理
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
[2] 其次我们看看BeanDefinitionParserDelegate的parseBeanDefinitionElement方法的核心解析过程文章源自JAVA秀-https://www.javaxiu.com/19908.html
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
//首先将Element对象转换成为AbstractBeanDefinition对象
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
//其次通过AbstractBeanDefinition对象,来初始化成BeanDefinitionHolder对象(也就是需要注册到beanDefinitionMap中的对象)。
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
[3] 我们进一步跟踪一下parseBeanDefinitionElement方法是如何将Element对象转换成为AbstractBeanDefinition对象的文章源自JAVA秀-https://www.javaxiu.com/19908.html
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
//首先创建一个不含任何具体信息的初始化的AbstractBeanDefinition对象
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//其次我们将Element对象的属性信息提取出来,初始化到AbstractBeanDefinition对象
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//然后我们将Element对象的meta标签信息提取出来,初始化到AbstractBeanDefinition对象
parseMetaElements(ele, bd);
//然后我们将lookup-method和replace-method信息从Element对象中提取出来,初始化到AbstractBeanDefinition对象
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//然后我们将构造参数信息从Element对象中提取出来,初始化到AbstractBeanDefinition对象
parseConstructorArgElements(ele, bd);
//然后我们将属性信息从Element对象中提取出来,初始化到AbstractBeanDefinition对象
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}
return null;
}
[4] 我们进一步跟踪一下parseBeanDefinitionAttributes方法是如何将Element对象信息,逐步的提取到AbstractBeanDefinition对象的文章源自JAVA秀-https://www.javaxiu.com/19908.html
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
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)));
}
//从Element对象提取lazyInit信息,并初始化到AbstractBeanDefinition对象
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
//从Element对象提取autowire信息,并初始化到AbstractBeanDefinition对象
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
bd.setAutowireMode(getAutowireMode(autowire));
//从Element对象提取dependencyCheck信息,并初始化到AbstractBeanDefinition对象
String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
//从Element对象提取autowireCandidate信息,并初始化到AbstractBeanDefinition对象
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));
}
//从Element对象提取PRIMARY_ATTRIBUTE信息,并初始化到AbstractBeanDefinition对象
if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
}
//从Element对象提取init-method信息,并初始化到AbstractBeanDefinition对象
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
if (!"".equals(initMethodName)) {
bd.setInitMethodName(initMethodName);
}
}
else {
if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
}
//从Element对象提取destroy-method信息,并初始化到AbstractBeanDefinition对象
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);
}
}
//从Element对象提取factory-method信息,并初始化到AbstractBeanDefinition对象
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;
}
通过上述逐步调用,我们终于了解了Element对象是如何被转换成为一个BeanDefinitionHolder对象的。文章源自JAVA秀-https://www.javaxiu.com/19908.html
文章源自JAVA秀-https://www.javaxiu.com/19908.html
更多知识请关注公众号文章源自JAVA秀-https://www.javaxiu.com/19908.html

评论