Spring實(shí)現(xiàn)默認(rèn)標(biāo)簽解析流程
本文實(shí)例為大家分享了Spring實(shí)現(xiàn)默認(rèn)標(biāo)簽解析流程的具體代碼,供大家參考,具體內(nèi)容如下
承接上文,進(jìn)入parseBeanDefinitions()方法
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { ?? ??? ?if (delegate.isDefaultNamespace(root)) { ?? ??? ??? ?NodeList nl = root.getChildNodes(); ?? ??? ??? ?for (int i = 0; i < nl.getLength(); i++) { ?? ??? ??? ??? ?Node node = nl.item(i); ?? ??? ??? ??? ?if (node instanceof Element) { ?? ??? ??? ??? ??? ?Element ele = (Element) node; ?? ??? ??? ??? ??? ?if (delegate.isDefaultNamespace(ele)) { ?? ??? ??? ??? ??? ??? ?//默認(rèn)標(biāo)簽解析,此次著重分析這個(gè)方法 ?? ??? ??? ??? ??? ??? ?parseDefaultElement(ele, delegate); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?else { ?? ??? ??? ??? ??? ??? ?//自定義標(biāo)簽解析 ?? ??? ??? ??? ??? ??? ?delegate.parseCustomElement(ele); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ?? ??? ?else { ?? ??? ??? ?delegate.parseCustomElement(root); ?? ??? ?} ?? ?}
-進(jìn)入parseDefaultElement()方法,此方法在parseBeanDefinitions的下方
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { ?? ??? ?//import標(biāo)簽解析 ,可看可不看 ?? ??? ?if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { ?? ??? ??? ?importBeanDefinitionResource(ele); ?? ??? ?} ?? ??? ?//alias標(biāo)簽解析 別名標(biāo)簽 可看可不看 ?? ??? ?else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { ?? ??? ??? ?processAliasRegistration(ele); ?? ??? ?} ?? ??? ?//bean標(biāo)簽,重要(看這個(gè)方法) ?? ??? ?else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { ?? ??? ??? ?processBeanDefinition(ele, delegate); ?? ??? ?} ?? ??? ?//beans標(biāo)簽,不重要 ?? ??? ?else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { ?? ??? ??? ?// recurse ?? ??? ??? ?doRegisterBeanDefinitions(ele); ?? ??? ?} ?? ?}
-進(jìn)入到bean標(biāo)簽解析方法
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { ?? ??? ?//重點(diǎn)看這個(gè)方法 ,解析document,封裝成BeanDefinition ?? ??? ?BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); ?? ??? ?if (bdHolder != null) { ?? ??? ??? ?bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); ?? ??? ??? ?try { ?? ??? ??? ??? ?//完成document到BeanDefinition對(duì)象轉(zhuǎn)換后,對(duì)BeanDefinition對(duì)象進(jìn)行緩存注冊(cè) ?? ??? ??? ??? ?// 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)); ?? ??? ?} ?? ?}
進(jìn)入
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { ?? ??? ?//思考一下這個(gè)的第二個(gè)參數(shù)為啥要傳入null(BeanDefinition類型),進(jìn)入方法 ?? ??? ?return parseBeanDefinitionElement(ele, null); ?? ?}
打開parseBeanDefinitionElement方法
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) { ?? ??? ?//獲取id ?? ??? ?String id = ele.getAttribute(ID_ATTRIBUTE); ?? ??? ?//獲取別名 ?? ??? ?String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); ?? ??? ?//將別名添加到aliases內(nèi) ?? ??? ?List<String> aliases = new ArrayList<>(); ?? ??? ?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.isTraceEnabled()) { ?? ??? ??? ??? ?logger.trace("No XML 'id' specified - using '" + beanName + ?? ??? ??? ??? ??? ??? ?"' as bean name and " + aliases + " as aliases"); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?//檢查beanName是否重復(fù) ?? ??? ?if (containingBean == null) { ?? ??? ??? ?checkNameUniqueness(beanName, aliases, ele); ?? ??? ?} ?? ??? ?//<bean>標(biāo)簽解析的核心方法 ?? ??? ?AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); ?? ??? ?if (beanDefinition != null) { ?? ??? ??? ?......不重要的就不要看了,浪費(fèi)時(shí)間 ?? ??? ?} ?? ??? ?return null; ?? ?}
看核心方法parseBeanDefinitionElement
public AbstractBeanDefinition parseBeanDefinitionElement( ?? ??? ??? ?Element ele, String beanName, @Nullable BeanDefinition containingBean) { ?? ??? ?this.parseState.push(new BeanEntry(beanName)); ?? ??? ?String className = null; ?? ??? ?if (ele.hasAttribute(CLASS_ATTRIBUTE)) { ?? ??? ??? ?className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); ?? ??? ?} ?? ??? ?String parent = null; ?? ??? ?if (ele.hasAttribute(PARENT_ATTRIBUTE)) { ?? ??? ??? ?parent = ele.getAttribute(PARENT_ATTRIBUTE); ?? ??? ?} ?? ??? ?try { ?? ??? ??? ?//創(chuàng)建GenericBeanDefinition對(duì)象 ?? ??? ??? ?AbstractBeanDefinition bd = createBeanDefinition(className, parent); ?? ??? ??? ?//解析bean標(biāo)簽的屬性,并把解析出來(lái)的屬性設(shè)置到BeanDefinition對(duì)象中 ?? ??? ??? ?parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); ?? ??? ??? ?bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); ?? ??? ??? ?//解析bean中的meta標(biāo)簽 ?? ??? ??? ?parseMetaElements(ele, bd); ?? ??? ??? ?//解析bean中的lookup-method標(biāo)簽 ?,可看可不看 ?? ??? ??? ?parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); ?? ??? ??? ?//解析bean中的replaced-method標(biāo)簽 ?,可看可不看 ?? ??? ??? ?parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); ?? ??? ??? ?//解析bean中的constructor-arg標(biāo)簽 ,可看可不看 ?? ??? ??? ?parseConstructorArgElements(ele, bd); ?? ??? ??? ?//解析bean中的property標(biāo)簽 可看可不看 ?? ??? ??? ?parsePropertyElements(ele, bd); ?? ??? ??? ?//可以不看,用不到 ?? ??? ??? ?parseQualifierElements(ele, bd); ?? ??? ??? ?bd.setResource(this.readerContext.getResource()); ?? ??? ??? ?bd.setSource(extractSource(ele)); ?? ??? ??? ?return bd; ?? ??? ?} ?? ??? ??? ?......有興趣自己看 ?? ??? ?return null; ?? ?}
打開這個(gè)方法parseBeanDefinitionAttributes(),對(duì)BeanDefinition屬性進(jìn)行默認(rèn)的封裝,然后返回BeanDefinition對(duì)象
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 (isDefaultValue(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 (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)); ?? ??? ?} ?? ??? ?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; ?? ?}
然后回到processBeanDefinition方法,將BeanDefinition注冊(cè)到緩存中,此時(shí)看
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { ?? ??? ?//重點(diǎn)看這個(gè)方法,重要程度 5 ,解析document,封裝成BeanDefinition ?? ??? ?BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); ?? ??? ?if (bdHolder != null) { ?? ??? ??? ?//該方法功能不重要,設(shè)計(jì)模式重點(diǎn)看一下,裝飾者設(shè)計(jì)模式,加上SPI設(shè)計(jì)思想 ?? ??? ??? ?bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); ?? ??? ??? ?try { ?? ??? ??? ??? ?//完成document到BeanDefinition對(duì)象轉(zhuǎn)換后,對(duì)BeanDefinition對(duì)象進(jìn)行緩存注冊(cè) ?? ??? ??? ??? ?// 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)); ?? ??? ?} ?? ?}
打開registerBeanDefinition方法
public static void registerBeanDefinition( ?? ??? ??? ?BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) ?? ??? ??? ?throws BeanDefinitionStoreException { ?? ??? ?// Register bean definition under primary name. ?? ??? ?String beanName = definitionHolder.getBeanName(); ?? ??? ?//完成BeanDefinition的注冊(cè),重點(diǎn)看 ?? ??? ?registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); ?? ??? ?//建立別名和 id的映射,這樣就可以根據(jù)別名獲取到id ?? ??? ?// Register aliases for bean name, if any. ?? ??? ?String[] aliases = definitionHolder.getAliases(); ?? ??? ?if (aliases != null) { ?? ??? ??? ?for (String alias : aliases) { ?? ??? ??? ??? ?registry.registerAlias(beanName, alias); ?? ??? ??? ?} ?? ??? ?} ?? ?}
打開registerBeanDefinition方法,將創(chuàng)建好的beanDefinition存入map。默認(rèn)標(biāo)簽解析就此完畢
@Override ?? ?public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) ?? ??? ??? ?throws BeanDefinitionStoreException { ?? ??? ?Assert.hasText(beanName, "'beanName' must not be empty"); ?? ??? ?Assert.notNull(beanDefinition, "BeanDefinition must not be null"); ?? ??? ?this.beanDefinitionMap.put(beanName, beanDefinition); ?? ?}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot使用thymeleaf動(dòng)態(tài)模板實(shí)現(xiàn)刷新
這篇文章主要介紹了Springboot使用thymeleaf動(dòng)態(tài)模板實(shí)現(xiàn)刷新,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08Java項(xiàng)目中如何訪問WEB-INF下jsp頁(yè)面
這篇文章主要介紹了Java項(xiàng)目中如何訪問WEB-INF下jsp頁(yè)面,文章通過示例代碼和圖文解析介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08Spring Cloud Netflix架構(gòu)淺析(小結(jié))
這篇文章主要介紹了Spring Cloud Netflix架構(gòu)淺析(小結(jié)),詳解的介紹了Spring Cloud Netflix的概念和組件等,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01