国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring源碼閱讀——ClassPathXmlApplicationContext(四)

ixlei / 1387人閱讀

摘要:在的方法中,遍歷每一個(gè)節(jié)點(diǎn),判斷是否為默認(rèn)命名空間中的節(jié)點(diǎn),如果是非默認(rèn)命名空間的,調(diào)用方法進(jìn)行處理。在學(xué)習(xí)自定義標(biāo)簽解析之前,先寫(xiě)一個(gè)自定義標(biāo)簽的。

在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一個(gè)節(jié)點(diǎn),判斷是否為默認(rèn)命名空間中的節(jié)點(diǎn),如果是非默認(rèn)命名空間的,調(diào)用delegate.parseCustomElement(ele)方法進(jìn)行處理。在學(xué)習(xí)自定義標(biāo)簽解析之前,先寫(xiě)一個(gè)自定義標(biāo)簽的demo。

一、自定義標(biāo)簽示例

定義POJO

下面定義一個(gè)Person類

package com.demo.beans.custom;

/**
 *@author zhzhd
 *@date 2018/6/11
 *@package 
 *@describe
 **/
public class Person {
    private String userName;
    private String sex;
    private Integer age;

    public Person(String name){
        this.userName = name;
    }
   ......省略setter和getter
}

定義一個(gè)文件描述組件

在webapp下創(chuàng)建person.xsd文件,內(nèi)容如下:



    
        
            
                
                    
                
            
        
        
            
                
                    
                
            
        
        
            
                
                    
                
            
        
        
            
                
                    
                
            
        
    

    
        
            
        
    

自定義NamespaceHandler

自定義MyNamespaceHandler,繼承NamespaceHandlerSupport,并且重寫(xiě)init()方法,實(shí)現(xiàn)如下:

package com.demo.beans.custom;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

/**
 *@author zhzhd
 *@date 2018/6/11
 *@package com.demo.beans.custom
 *@describe
 **/
public class MyNamespaceHandler extends NamespaceHandlerSupport{
    public void init() {
        registerBeanDefinitionParser("", new PersonBeanDefinitionParser());
    }
}

實(shí)現(xiàn)自定義PersonBeanDefinitionParser

自定義實(shí)現(xiàn)PersonBeanDefinitionParser,并且重寫(xiě)Class getBeanClass(Element element)和doParse(Element element, BeanDefinitionBuilder bean)方法。getBeanClass方法返回當(dāng)前bean的class,doParse解析自定義元素屬性,實(shí)現(xiàn)如下:

package com.demo.beans.custom;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;

/**
 *@author zhzhd
 *@date 2018/6/11
 *@package com.demo.beans.custom
 *@describe
 **/
public class PersonBeanDefinitionParser extends AbstractSingleBeanDefinitionParser{

    @Override
    protected Class getBeanClass(Element element){
        return Person.class;
    }

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder bean){
        String name = element.getAttribute("name");
        bean.addConstructorArgValue(name);
        if (StringUtils.hasText(name)){
            bean.addConstructorArgValue(name);
        }

        String age = element.getAttribute("age");
        String sex = element.getAttribute("sex");
        if (StringUtils.hasText(age)){
            bean.addPropertyValue("age", Integer.parseInt(age));
        }
        if (StringUtils.hasText(age)){
            bean.addPropertyValue("sex", sex);
        }
    }
}

創(chuàng)建spring.handlers和spring.schemas

http://www.zhzhd.com/schema/person=com.demo.beans.custom.MyNamespaceHandler
http://www.zhzhd.com/schema/person.xsd=person.xsd

在XML中配置bean以及測(cè)試

接下來(lái),需要在spring的配置文件中加入命名空間信息,并且配置自定義bean,實(shí)現(xiàn)如下:



    

測(cè)試demo如下:

    public static void main(String[] args) {
        BeanFactory beanFactory1 = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        ApplicationContext beanFactory = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"},true);
        Person person = beanFactory.getBean("testPerson", Person.class);
        System.out.println(JSON.toJSONString(person));
    }

從上面的示例可以看到,我們定義了自定義節(jié)點(diǎn)的handler,spring在解析xml中節(jié)點(diǎn)或?qū)傩缘臅r(shí)候,當(dāng)遇到自定義節(jié)點(diǎn)和屬性時(shí),會(huì)調(diào)用響應(yīng)的handler進(jìn)行解析,下面具體分析自定義節(jié)點(diǎn)和屬性解析的源碼。

二、spring解析自定義標(biāo)簽的源碼分析

首先,從xml元素的解析開(kāi)始分析,在parseBeanDefinitions()方法中,判斷如果是xml中節(jié)點(diǎn)或?qū)傩允亲远x的,則調(diào)用BeanDefinitionParserDelegate的parseCustomElement()方法處理,下面是parseCustomElement()的實(shí)現(xiàn):

    public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
        // 讀取命名空間url
        String namespaceUri = getNamespaceURI(ele);
        if (namespaceUri == null) {
            return null;
        }
        // 解析命名空間,返回NamespaceHandler實(shí)例
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
        if (handler == null) {
            error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
            return null;
        }
        // 解析自定義標(biāo)簽
        return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    }

從Element中獲取到自定義命名空間uri后,交給DefaultNamespaceHandlerResolver的resolve()方法解析并實(shí)例化NamespaceHandler實(shí)例,具體實(shí)現(xiàn)如下:

public NamespaceHandler resolve(String namespaceUri) {
        // 獲取命名空間uri和handler類名關(guān)系map
        Map handlerMappings = getHandlerMappings();
        // 獲取類名
        Object handlerOrClassName = handlerMappings.get(namespaceUri);
        if (handlerOrClassName == null) {
            return null;
        }
        else if (handlerOrClassName instanceof NamespaceHandler) {
            return (NamespaceHandler) handlerOrClassName;
        }
        else {
            String className = (String) handlerOrClassName;
            try {
                Class handlerClass = ClassUtils.forName(className, this.classLoader);
                if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
                    throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
                            "] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
                }
                // 實(shí)例化NamespaceHandler
                NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
                // 初始化NamespaceHandler
                namespaceHandler.init();
                handlerMappings.put(namespaceUri, namespaceHandler);
                return namespaceHandler;
            }
            catch (ClassNotFoundException ex) {
                throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
                        "] for namespace [" + namespaceUri + "]", ex);
            }
            catch (LinkageError err) {
                throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
                        className + "] for namespace [" + namespaceUri + "]", err);
            }
        }
    }

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/76390.html

相關(guān)文章

  • Spring源碼閱讀——ClassPathXmlApplicationContext

    摘要:在的方法中,遍歷每一個(gè)節(jié)點(diǎn),判斷是否為默認(rèn)命名空間中的節(jié)點(diǎn),如果是非默認(rèn)命名空間的,調(diào)用方法進(jìn)行處理。在學(xué)習(xí)自定義標(biāo)簽解析之前,先寫(xiě)一個(gè)自定義標(biāo)簽的。 在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一...

    silenceboy 評(píng)論0 收藏0
  • Spring源碼閱讀——ClassPathXmlApplicationContext

    摘要:在的方法中,遍歷每一個(gè)節(jié)點(diǎn),判斷是否為默認(rèn)命名空間中的節(jié)點(diǎn),如果是非默認(rèn)命名空間的,調(diào)用方法進(jìn)行處理。在學(xué)習(xí)自定義標(biāo)簽解析之前,先寫(xiě)一個(gè)自定義標(biāo)簽的。 在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一...

    wmui 評(píng)論0 收藏0
  • Spring源碼閱讀——ClassPathXmlApplicationContext(一)

    摘要:的繼承關(guān)系繼承了,實(shí)現(xiàn)了接口。是所有容器的頂級(jí)接口,中所有容器都是基于的。方法創(chuàng)建一個(gè)新的容器。在本方法中,最重要的是,調(diào)用這個(gè)方法解析配置文件,注冊(cè)。 ClassPathXmlApplicationContext的繼承關(guān)系 ClassPathXmlApplicationContext繼承了AbstractXmlApplicationContext,實(shí)現(xiàn)了ApplicationCont...

    taowen 評(píng)論0 收藏0
  • Spring源碼閱讀——ClassPathXmlApplicationContext(三)

    摘要:在上一篇源碼閱讀二文章的最后,需要解析元素,創(chuàng)建實(shí)例完成必須的裝配和進(jìn)行最終的注冊(cè)來(lái)完成元素的解析和注冊(cè),下面分別閱讀三步的源碼。 在上一篇Spring源碼閱讀——ClassPathXmlApplicationContext(二)文章的最后,需要解析bean元素,創(chuàng)建BeanDefinitionHolder實(shí)例、完成必須的裝配和進(jìn)行最終的注冊(cè)bean來(lái)完成bean元素的解析和注冊(cè),下面...

    xbynet 評(píng)論0 收藏0
  • Spring源碼閱讀——ClassPathXmlApplicationContext(三)

    摘要:在上一篇源碼閱讀二文章的最后,需要解析元素,創(chuàng)建實(shí)例完成必須的裝配和進(jìn)行最終的注冊(cè)來(lái)完成元素的解析和注冊(cè),下面分別閱讀三步的源碼。 在上一篇Spring源碼閱讀——ClassPathXmlApplicationContext(二)文章的最后,需要解析bean元素,創(chuàng)建BeanDefinitionHolder實(shí)例、完成必須的裝配和進(jìn)行最終的注冊(cè)bean來(lái)完成bean元素的解析和注冊(cè),下面...

    AndroidTraveler 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<