<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 1.1 Spring自定義標簽過程 Spring支持自定義標簽,主要過程為: 1.設置標簽的屬性,并編寫xsd文件 2.編寫標簽對應的JavaBean 3.編寫NamespaceHandler和BeanDefinitionParser完成解析工作 4.編寫spring.handlers和spring.schemas串聯起所有部件 5.從Spring容器獲取實例并測試 涉及的文件: * xsd文件 * JavaBean.java 標簽對應的Bean * NamespaceHandler * BeanDefinitionParser * spring.handlers * spring.schemas **xsd** xsd是xml schema definition的縮寫,用來代替dtd文件,定義xml文件的規則。我們擴展Spring自定義標簽時,使用xsd用于描述標簽的規則。具體教程可見 [xsd教程](http://www.w3school.com.cn/schema/schema_intro.asp)。 在 XML 中,元素名稱是由開發者定義的,當兩個不同的文檔使用相同的元素名時,就會發生命名沖突。spring的xml文件中會設置引用到的命名空間,xsd內部也會設置標簽的命名空間, **JavaBean** 這個類與標簽相對應,根據標簽的屬性及其內容設置類中對應的屬性。比如,dubbo的`<dubbo:service>`標簽對應的是ServiceBean,內部保存了服務器的配置信息。 **NamespaceHandler** Spring讀取xml文件時,會根據標簽的命名空間找到其對應的NamespaceHandler,我們在NamespaceHandler內會注冊標簽對應的解析器BeanDefinitionParser。 **BeanDefinitionParser** BeanDefinitionParser是標簽對應的解析器,Spring讀取到對應標簽時會使用該類進行解析; **spring.handlers** 內部保存命名空間與NamespaceHandler類的對應關系;必須放在classpath下的META-INF文件夾中。 **spring.schemas** 內部保存命名空間對應的xsd文件位置;必須放在classpath下的META-INF文件夾中。 ![自定義標簽解析流程](http://www.uxiaowo.com/dubbo/EleParse.png) ## 1.2 Spring自定義標簽實例 **目標** 我們要實現一個Proxy類,其實現了Info接口 ``` public interface Info { public String getInfo(); } ``` Proxy類內部保存了 private Info delegate;調用getInfo時實際上會調用delegate的getInfo。 ``` private Info delegate; public String getInfo() { preDelgate(); String result = delegate.getInfo(); return postDelgate(result); } ``` 我們要定義一個proxy標簽,實現這個功能,我們將命名空間設置為`http://study.shisj.com/schema/proxy`,前綴設置為`dubboStudy`,proxy標簽有三個屬性: * name 代理的名稱 * class 代理的接口 * ref,引用一個Info實例 **proxy.xsd** 有了標簽的屬性就可以定義xsd文件了,targetNamespace是標簽proxy的命名空間 ``` <?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://study.shisj.com/schema/proxy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://study.shisj.com/schema/proxy" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.springframework.org/schema/beans" /> <xsd:element name="proxy"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="class" type="xsd:string" /> <xsd:attribute name="ref" type="xsd:string" /> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema> ``` **Proxy.java** ``` public class Proxy implements Info{ private String id; private String name; private Info delegate; private String ref; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getInfo() { preDelgate(); String result = delegate.getInfo(); return postDelgate(result); } public Info getDelegate() { return delegate; } public void setDelegate(Info delegate) { this.delegate = delegate; } private void preDelgate() { } private String postDelgate(String result) { return result; } public String getRef() { return ref; } public void setRef(String ref) { this.ref = ref; } } ``` **NamespaceHandler** 定義命名空間的處理器,內部設置了proxy標簽的解析器 ``` public class MyNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("proxy", new ProxyBeanDefinitionParser()); } } ``` **ProxyBeanDefinitionParser** Spring解析到proxy標簽時會調用這個類進行解析生成實例 ``` public class ProxyBeanDefinitionParser implements BeanDefinitionParser { public BeanDefinition parse(Element element, ParserContext parserContext) { RootBeanDefinition beanDefinition = new RootBeanDefinition(); String name = element.getAttribute("name"); beanDefinition.setBeanClass(Proxy.class); beanDefinition.setLazyInit(false); String id = element.getAttribute("id"); String ref = element.getAttribute("ref"); if (StringUtils.hasText(id)) { beanDefinition.getPropertyValues().addPropertyValue("id", id); } if (StringUtils.hasText(name)) { beanDefinition.getPropertyValues().addPropertyValue("name", name); } if (StringUtils.hasText(ref)) { beanDefinition.getPropertyValues().addPropertyValue("delegate", new RuntimeBeanReference(ref)); } parserContext.getRegistry().registerBeanDefinition(id, beanDefinition); return beanDefinition; } } ``` **spring.handlers** 告訴Spring如何根據命名空間后如何查找`命名空間處理器` ``` http\://study.shisj.com/schema/proxy=com.shisj.study.dubbo.spring.MyNamespaceHandler ``` **spring.schemas** 通知Spring如何根據命名空間后如何查找對應的xsd文件 ``` http\://study.shisj.com/schema/proxy.xsd=META-INF/proxy.xsd ``` **測試程序** 下面是Spring的配置文件,內部指定了前綴dubboStudy的命名空間為`http://study.shisj.com/schema/prox`,在`xsi:schemaLocation`中指定schema文件的位置 ``` <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubboStudy="http://study.shisj.com/schema/proxy" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://study.shisj.com/schema/proxy http://study.shisj.com/schema/proxy.xsd"> <dubboStudy:proxy id="proxy" name="myhome" class="com.shisj.study.dubbo.spring.Info" ref="beijing"/> <!--AddressInfo會輸出地址信息--> <bean id="beijing" class="com.shisj.study.dubbo.spring.AddressInfo"> <property name="country" value="China"/> <property name="province" value="Beijing"/> <property name="city" value="Beijing"/> </bean> </beans> ``` Java測試 ``` ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-proxy.xml"); Proxy proxy = (Proxy) ctx.getBean("proxy"); System.out.println(proxy.getInfo()); // 調用AddressInfo的getInfo() // [Addr] country:China,province:Beijing,city:Beijing ``` ## dubbo標簽相關文件 dubbo標簽的前綴為dubbo,命名空間為http://code.alibabatech.com/schema/dubbo ``` xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation=“ http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd" ``` * XSD文件:dubbo.xsd * com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler ### DubboNamespaceHandler 根據dubbo的命名空間會使用這個類查找標簽對應的解析器 ``` registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true)); registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true)); registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true)); registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true)); registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true)); registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true)); registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true)); registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true)); registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false)); registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true)); ``` ### DubboBeanDefinitionParser DubboBeanDefinitionParser用來處理所有標簽的解析,主要流程是: 1. 創建RootBeanDefinition,內部保存了Bean的信息,便于后續初始化生成實例,主要有兩個屬性:BeanClass,指定的Class類型,解析標簽時對應的是保存標簽數據的類;LazyInit:是否延遲初始化,一般都會設置為false,即不在Spring啟動過程中初始化實例。 2. 獲取id,若require為true,必須要有id,從id > name > interface 獲取,若有重復,后面自帶加count 3. 向Spring的ParserContext中注冊id和BeanDefinition的對應關系 4. 根據BeanClass通過反射查找set方法,從標簽屬性中獲取對應的值并設置。 5. 其他還有針對不同標簽設置的邏輯。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看