Spring配置文件解析之BeanDefinitionParserDelegate詳解
Spring的BeanDefinitionParserDelegate
上一篇Spring配置文件解析之BeanDefinitionDocumentReader詳解中我們已經(jīng)了解到對于Spring的配置文件的解析處理操作是在BeanDefinitionParserDelegate中進行處理操作,接下來我們簡單介紹一下BeanDefinitionParserDelegate所做的處理操作。
首先BeanDefinitionParserDelegate中定義了其會解析xml的spring元素標簽,并且還有說明一點的是Spring解析xml的標簽是通過命名空間Namespace來決定的,BeanDefinitionParserDelegate中定義了如下命名空間,只會支持解析這個命名空間中的標簽元素。
public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
BeanDefinitionParserDelegate中定義的spring的標簽元素如下:
public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans"; public static final String MULTI_VALUE_ATTRIBUTE_DELIMITERS = ",; "; public static final String TRUE_VALUE = "true"; public static final String FALSE_VALUE = "false"; public static final String DEFAULT_VALUE = "default"; public static final String DESCRIPTION_ELEMENT = "description"; public static final String AUTOWIRE_NO_VALUE = "no"; public static final String AUTOWIRE_BY_NAME_VALUE = "byName"; public static final String AUTOWIRE_BY_TYPE_VALUE = "byType"; public static final String AUTOWIRE_CONSTRUCTOR_VALUE = "constructor"; public static final String AUTOWIRE_AUTODETECT_VALUE = "autodetect"; public static final String DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE = "all"; public static final String DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE = "simple"; public static final String DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE = "objects"; public static final String NAME_ATTRIBUTE = "name"; public static final String BEAN_ELEMENT = "bean"; public static final String META_ELEMENT = "meta"; public static final String ID_ATTRIBUTE = "id"; public static final String PARENT_ATTRIBUTE = "parent"; public static final String CLASS_ATTRIBUTE = "class"; public static final String ABSTRACT_ATTRIBUTE = "abstract"; public static final String SCOPE_ATTRIBUTE = "scope"; private static final String SINGLETON_ATTRIBUTE = "singleton"; public static final String LAZY_INIT_ATTRIBUTE = "lazy-init"; public static final String AUTOWIRE_ATTRIBUTE = "autowire"; public static final String AUTOWIRE_CANDIDATE_ATTRIBUTE = "autowire-candidate"; public static final String PRIMARY_ATTRIBUTE = "primary"; public static final String DEPENDENCY_CHECK_ATTRIBUTE = "dependency-check"; public static final String DEPENDS_ON_ATTRIBUTE = "depends-on"; public static final String INIT_METHOD_ATTRIBUTE = "init-method"; public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method"; public static final String FACTORY_METHOD_ATTRIBUTE = "factory-method"; public static final String FACTORY_BEAN_ATTRIBUTE = "factory-bean"; public static final String CONSTRUCTOR_ARG_ELEMENT = "constructor-arg"; public static final String INDEX_ATTRIBUTE = "index"; public static final String TYPE_ATTRIBUTE = "type"; public static final String VALUE_TYPE_ATTRIBUTE = "value-type"; public static final String KEY_TYPE_ATTRIBUTE = "key-type"; public static final String PROPERTY_ELEMENT = "property"; public static final String REF_ATTRIBUTE = "ref"; public static final String VALUE_ATTRIBUTE = "value"; public static final String LOOKUP_METHOD_ELEMENT = "lookup-method"; public static final String REPLACED_METHOD_ELEMENT = "replaced-method"; public static final String REPLACER_ATTRIBUTE = "replacer"; public static final String ARG_TYPE_ELEMENT = "arg-type"; public static final String ARG_TYPE_MATCH_ATTRIBUTE = "match"; public static final String REF_ELEMENT = "ref"; public static final String IDREF_ELEMENT = "idref"; public static final String BEAN_REF_ATTRIBUTE = "bean"; public static final String LOCAL_REF_ATTRIBUTE = "local"; public static final String PARENT_REF_ATTRIBUTE = "parent"; public static final String VALUE_ELEMENT = "value"; public static final String NULL_ELEMENT = "null"; public static final String ARRAY_ELEMENT = "array"; public static final String LIST_ELEMENT = "list"; public static final String SET_ELEMENT = "set"; public static final String MAP_ELEMENT = "map"; public static final String ENTRY_ELEMENT = "entry"; public static final String KEY_ELEMENT = "key"; public static final String KEY_ATTRIBUTE = "key"; public static final String KEY_REF_ATTRIBUTE = "key-ref"; public static final String VALUE_REF_ATTRIBUTE = "value-ref"; public static final String PROPS_ELEMENT = "props"; public static final String PROP_ELEMENT = "prop"; public static final String MERGE_ATTRIBUTE = "merge"; public static final String QUALIFIER_ELEMENT = "qualifier"; public static final String QUALIFIER_ATTRIBUTE_ELEMENT = "attribute"; public static final String DEFAULT_LAZY_INIT_ATTRIBUTE = "default-lazy-init"; public static final String DEFAULT_MERGE_ATTRIBUTE = "default-merge"; public static final String DEFAULT_AUTOWIRE_ATTRIBUTE = "default-autowire"; public static final String DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE = "default-dependency-check"; public static final String DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE = "default-autowire-candidates"; public static final String DEFAULT_INIT_METHOD_ATTRIBUTE = "default-init-method"; public static final String DEFAULT_DESTROY_METHOD_ATTRIBUTE = "default-destroy-method";
接下來我們看一下對一個簡單的bean注入的配置的解析處理操作。
<bean id="transaction" name="transaction" class="com.xxxx.aop.two.Transaction"></bean>
這里需要解析的元素有id,name和class三個標簽,在上面均有定義。
在parseBeanDefinitionElement中會完成id和name標簽的解析處理操作,并最終生成BeanDefinitionHolder返回,class標簽的元素解析在parseBeanDefinitionElement中處理
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { //解析id String id = ele.getAttribute(ID_ATTRIBUTE); //解析name 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); } //解析其他元素標簽 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); //最終生成BeanDefinitionHolder return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; }
接下來我們看看對class標簽的解析處理操作。parseBeanDefinitionElement中會完成對class等其他標簽的解析處理操作,最終生成BeanDefinition返回。
public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); //解析class標簽內(nèi)容 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 bd = createBeanDefinition(className, parent); parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); parseMetaElements(ele, bd); parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); parseConstructorArgElements(ele, bd); parsePropertyElements(ele, bd); parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(extractSource(ele)); //最終生成BeanDefinition返回 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; }
總結(jié)
繞了那么一大圈,Spring配置文件的解析處理操作是在BeanDefinitionParserDelegate中完成,當然也是只是完成了對Beans這個命名空間中的元素的解析處理操作,對于其他的命名空間是通過其他解析器進行解析操作的,接下來我們會進行分析,BeanDefinitionParserDelegate做的處理操作就是將bean的各種標簽解析成BeanDefinition對象,并組裝成BeanDefinitionHolder返回。
到此這篇關(guān)于Spring配置文件解析之BeanDefinitionParserDelegate詳解的文章就介紹到這了,更多相關(guān)Spring的BeanDefinitionParserDelegate內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring MVC下 bootStrap服務(wù)器分頁代碼
因為Spring 對于ajax直接返回對象,到了WEB頁面就轉(zhuǎn)換成json 所以不需要使用JSON轉(zhuǎn)換封裝可以直接使用。接下來通過本文給大家分享Spring MVC下 bootStrap服務(wù)器分頁代碼,需要的的朋友參考下2017-03-03劍指Offer之Java算法習(xí)題精講字符串與二叉搜索樹
跟著思路走,之后從簡單題入手,反復(fù)去看,做過之后可能會忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質(zhì)的變化2022-03-03Spring使用@Value注解與@PropertySource注解加載配置文件操作
這篇文章主要介紹了Spring使用@Value注解與@PropertySource注解加載配置文件操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06Java中IdentityHashMap與HashMap區(qū)別詳解
這篇文章主要介紹了Java中IdentityHashMap與HashMap區(qū)別詳解,很多人不曉得IdentityHashMap的存在,其中不乏工作很多年的Java開發(fā)者,他們看到就說是第三方j(luò)ar包,實際上它是Jdk源碼自帶的集合類,需要的朋友可以參考下2023-11-11java sql ResultSet 之getRow()用法說明
這篇文章主要介紹了java sql ResultSet 之getRow()用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08