最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring實(shí)現(xiàn)默認(rèn)標(biāo)簽解析流程

 更新時(shí)間:2022年01月16日 11:55:14   作者:大大明001  
這篇文章主要為大家詳細(xì)介紹了Spring實(shí)現(xiàn)默認(rèn)標(biāo)簽解析流程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(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類(lèi)型),進(jìn)入方法
?? ??? ?return parseBeanDefinitionElement(ele, null);
?? ?}

打開(kāi)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;
?? ?}

打開(kāi)這個(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));
?? ??? ?}
?? ?}

打開(kāi)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);
?? ??? ??? ?}
?? ??? ?}
?? ?}

打開(kāi)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)文章

  • Mybatis-Plus主鍵插入null值報(bào)錯(cuò)問(wèn)題及解決

    Mybatis-Plus主鍵插入null值報(bào)錯(cuò)問(wèn)題及解決

    這篇文章主要介紹了Mybatis-Plus主鍵插入null值報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • springboot無(wú)法從靜態(tài)上下文中引用非靜態(tài)變量的解決方法

    springboot無(wú)法從靜態(tài)上下文中引用非靜態(tài)變量的解決方法

    這篇文章主要介紹了springboot無(wú)法從靜態(tài)上下文中引用非靜態(tài)變量的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-06-06
  • springmvc+spring+mybatis實(shí)現(xiàn)用戶(hù)登錄功能(上)

    springmvc+spring+mybatis實(shí)現(xiàn)用戶(hù)登錄功能(上)

    這篇文章主要為大家詳細(xì)介紹了springmvc+spring+mybatis實(shí)現(xiàn)用戶(hù)登錄功能,比較基礎(chǔ)的學(xué)習(xí)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Java 8中Collectors.toMap空指針異常源碼解析

    Java 8中Collectors.toMap空指針異常源碼解析

    這篇文章主要為大家介紹了Java 8中Collectors.toMap空指針異常源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • java發(fā)起http請(qǐng)求調(diào)用post與get接口的方法實(shí)例

    java發(fā)起http請(qǐng)求調(diào)用post與get接口的方法實(shí)例

    在實(shí)際開(kāi)發(fā)過(guò)程中,我們經(jīng)常需要調(diào)用對(duì)方提供的接口或測(cè)試自己寫(xiě)的接口是否合適,下面這篇文章主要給大家介紹了關(guān)于java發(fā)起http請(qǐng)求調(diào)用post與get接口的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • Java邏輯運(yùn)算符之&&、||?與&、?|的區(qū)別及應(yīng)用

    Java邏輯運(yùn)算符之&&、||?與&、?|的區(qū)別及應(yīng)用

    這篇文章主要介紹了Java邏輯運(yùn)算符之&&、||?與&、?|的區(qū)別及應(yīng)用的相關(guān)資料,分別是&&、||?與&、?|,并探討了它們?cè)诓煌瑧?yīng)用場(chǎng)景中的表現(xiàn)和優(yōu)化效果,需要的朋友可以參考下
    2025-03-03
  • springboot封裝響應(yīng)實(shí)體的實(shí)例代碼

    springboot封裝響應(yīng)實(shí)體的實(shí)例代碼

    這篇文章主要介紹了springboot封裝響應(yīng)實(shí)體,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Java中的FileWriter用法詳解與實(shí)戰(zhàn)記錄

    Java中的FileWriter用法詳解與實(shí)戰(zhàn)記錄

    這篇文章主要給大家介紹了關(guān)于Java中FileWriter用法的相關(guān)資料,包括寫(xiě)入字符數(shù)據(jù)到文件、字符數(shù)組和部分字符寫(xiě)入、配合BufferedWriter使用等方法,同時(shí)也解釋了其與OutputStreamWriter,BufferedWriter的異同特性,適合簡(jiǎn)單的文件寫(xiě)入操作,需要的朋友可以參考下
    2024-10-10
  • Java經(jīng)典面試題匯總:多線程

    Java經(jīng)典面試題匯總:多線程

    本篇總結(jié)的是Java多線程相關(guān)的面試題,后續(xù)會(huì)持續(xù)更新,希望我的分享可以幫助到正在備戰(zhàn)面試的實(shí)習(xí)生或者已經(jīng)工作的同行,如果發(fā)現(xiàn)錯(cuò)誤還望大家多多包涵,不吝賜教,謝謝
    2021-07-07
  • 使用Java語(yǔ)言實(shí)現(xiàn)一個(gè)冒泡排序

    使用Java語(yǔ)言實(shí)現(xiàn)一個(gè)冒泡排序

    冒泡排序也是一種簡(jiǎn)單直觀的排序算法,基本思想是多次遍歷要排序的數(shù)組,每次比較相鄰的元素,如果順序不對(duì)就交換它們的位置,本篇文章將通過(guò)IDE使用 Java 語(yǔ)言實(shí)現(xiàn)一個(gè)冒泡排序,需要的朋友可以參考下
    2024-03-03

最新評(píng)論

璧山县| 蒲城县| 临澧县| 楚雄市| 吴旗县| 大渡口区| 海晏县| 武乡县| 阿克苏市| 容城县| 楚雄市| 垦利县| 逊克县| 轮台县| 柳州市| 鹤庆县| 全椒县| 镇坪县| 东阳市| 定结县| 青冈县| 冕宁县| 新沂市| 丰都县| 清水河县| 凤凰县| 巨野县| 孝义市| 西华县| 滨海县| 上林县| 天水市| 虞城县| 南陵县| 枣庄市| 罗江县| 策勒县| 丰城市| 灌阳县| 宝兴县| 当雄县|