美文网首页
Spring XML中各种元素及属性的使用

Spring XML中各种元素及属性的使用

作者: 码而优则仕 | 来源:发表于2020-04-27 10:01 被阅读0次

创建用于属性承载的 BeanDefinition

BeanDefinition 是一个接口,在 Spring 中存在三种实现: RootBeanDefinition、 ChildBean­ Definition 以及 GenericBeanD巳finitiono 三 种实现均继承了 AbstractBeanDefiniton ,其中 BeanDefinition 是配置文件<bean>元素标签在容器中的内部表示形式 。 <bean>元素标签拥有 class、 scope、 lazy-init等配置属性, BeanDefinition则提供了相应的 beanClass、 scope、 lazyInit 属性, BeanD巳finition和<bean>中的属性是-一对应的。 其中 RootBeanDefinition是最常用的实 现类,它对应一般性的<bean>元素标签, GenericB巳anDefinition 是自 2.5 版本以后新加入的 bean 文件配置属性定义类,是一站式服务类 。

在配置文件中可以定义父<bean>和子<bean>,父<bean>用 RootBeanD巳finition 表示,而子 <bean>用 ChildBeanDefiniton 表示,而没有父<bean>的<bean>就使用 RootBeanDefinition 表示 。 AbstractBeanDefinition 对两者共同的类信息进行抽象 。

Spring通过 BeanDefinition将配置文件中的<bean>配置信息转换为容器的内部表示,并将 这些 BeanDefiniton 注册到 BeanDefinitonRegistry 中。Spring容器的 BeanDefinitionRegistrγ就像 是 Spring配置信息的内存数据库,主要是以 map 的形式保存,后续操作直接从 BeanDefinition­ Registry 中读取配置信息 。 它们之间的关系如图 3-2 所示 。

123123.png

解析子元素 lookup-method

同样,子元素 lookup-method 似乎并不是很常用,但是在某些时候它的确是非常有用的 属性,通常我们称它为获取器注入。 引用 Springin Action 中的一句话:获取器注入是一种特 殊的方法注入,它是把一个方法声明为返回某种类型的 bean,但实际要返回的 bean 是在配 置文件里面配置的,此方法可用在设计有些可插拔的功能上,解除程序依赖。 我们看看具体 的应用 。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n84" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;">1. 首先我们创建一个父类。
package test.lookup.bean,
public class User {
Public void showMe (){
System.out.println(”i am user”)}
}

  1. 创建其子类并覆盖showMe方法。
    package test.lookup.bean;
    public class Teacher extends User{
    public void showMe() {
    System out.println(”l am Teacher”),
    }
    public abstract User getBean();
    }
  2. 创建调用方法。
    public abstract class GetBeanTest {
    Public void showMe(){ this.getBean().showMe(); }
    public abstract User getBean () ; }
  3. 创建测试方法。
    package test.lookup;
    import org Springframework.context.ApplicationContext;
    import org . Springframework . coηtext support .ClassPathXmlApplicationContext;
    import test.lookup.app GetBeanTest;

    public class Main (
    public static void main(String[] args){
    ApplicationContext bf = new ClassPathXmlApplicationContext (”test/lookup/lookupTest .xml” ) ;
    GetBeanTest test= (GetBeanTest)bf.getBean( "getBeanTest ”);
    test.showMe() ;
    }

到现在为止,除了配置文件外,整个测试方法就完成了,如果之前没有接触过获取器注入
的读者们可能会有疑问:抽象方法还没有被实现,怎么可以直接调用呢?答案就在Spring为我
们提供的获取器中,我们看看配置文件是怎么配置的 。</pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n87" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;"><?xml version=”1 0” encoding="UTF-8”。〉
<beans xmlns=”http : //wwwSpringframework.org/schema/beans
xmlns:xsi =”http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=”http://www.springframework.org/schema/beans/springframework.org/schema/beans/Spring-beans.xsd”>
<bean id=”getBeanTest" class=”test.lookup.app.GetBeanTest”>
<lookup-method name="geBean" bean=teacher"/>
</bean>
<bean id=”teacher" class="test.lookup.bean.Teacher”/> </beans></pre>

在配置文件中,我们看到了源码解析中提到的 lookup-method子元素,这个配置完成的功能是 动态地将 teacher所代表的 bean作为 getBean 的返回值,运行测试方法我们会看到控制台上的输出 :

I am Teacher

当我们的业务变更或者在其他情况下, teacher 里面的业务逻辑已经不再符合我们的业务要 求,需要进行替换怎么办呢?这是我们需要增加新的逻辑类 :

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n102" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;">package test lookup .bean ;
public class Student extends User{
public void showMe (){
System.out.println("i am student");
}
} </pre>

同 时修改配置文件:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n109" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;"><?xml version=”1 0” encoding="UTF-8”。〉
<beans xmlns=”http : //wwwSpringframework.org/schema/beans
xmlns:xsi =”http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=”http://www.springframework.org/schema/beans/springframework.org/schema/beans/Spring-beans.xsd”>
<bean id=”getBeanTest" class=”test.lookup.app.GetBeanTest”>
<lookup-method name="geBean" bean=student"/>
</bean>
<bean id=”teacher" class="test.lookup.bean.Teacher”/> </beans>
<bean id=”student” class=”test lookup.bean.Student”/></pre>

解析子元素 replaced-method

方法替换:可以在运行时用新的方法替换现有的方法 。 与之前的 look-up 不同的是, replaced-method不但可以动态地替换返回实体 bean,而且还能动态地更改原有方法的逻辑。 我 们来看看使用示例 。

  1. 在 changeMe 中完成某个业务逻辑。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n131" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">public class TestChangeMethod {
    public void changeMe(){
    System.out.println("changeMe");
    }
    }</pre>

  2. 在运营一段时间后需要改变原有的业务逻辑 。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n146" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">public class TestMethodRεplacer implements MethodReplacer{
    @Override
    public Object ceimplement(Object obj , Method method, Object[] args)throws Throwable { System.out.println(”我替换了原有的方法”);
    return null; }
    }
    ​</pre>

  3. 使替换后的类生效。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n156" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;"><?xml version =”1.0” encoding=”UTF-8”?〉
    <beans xmlns=”http://www.Springframework.org/schema/beans" xmlns:xsi=”http://www.w3org/2001/XMLSchema-instance
    xs1:schemaLocation="http://wwwSpringframework.org/schema/beans http://www.Springframework.org/schema/beans/Spring-beans.xsd">
    <bean id=”testChangeMethod” class=”testreplacemethod.TestChangeMethod”> <replaced-method name=”changeMe” replacer="replacer"/>
    </bean>
    <bean id="replacer" class=”testreplacemethod.TestMethodReplacer"/> </beans>
    ​</pre>

  4. 测试

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n163" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">public static void main(String []args) {
    ApplicationContext bf = new ClassPathXmlApplicationContext(”test/replacemethod/replaceMethodTest.xml”);
    TestChangeMethod test=(TestChangeMethod) bf.getBean ("testChangeMethod");
    test.changeMe();}</pre>

Property使用

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n189" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;"><bean id=”test” class=”test.TestClass”>
<property name=” testStr” value=” aaa” /> </bean>
或者
<bean id= "a ” >
<property name="p”>
<list> <value>aa</value>
<value>bb</value>
</list> </property>
</bean></pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n194" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;"><bean id=”test” class=”test.MyClass”>
<mybean:user username=”aaa”/>
</bean></pre>

alias的使用

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n201" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;"><bean id=”testBean” class=”com.test” />

<bean id=”testBean” name=”testBean,tescBean2” class="com.test"/>

<bean id=”testBean” class=”corn.test”/>
<alias name=”testBean” alias=”testBean,testBean2”/〉</pre>

考虑一个更为具体的例子,组件 A 在 XML 配置文件中定义了一个名为 componentA 的 DataSource 类型的 bean,但组件B 却想在其 XML 文件中以 componentB 命名来引用此 bean。 而且在主程序 MyApp 的 XML配置文件中,希望以 myApp 的名字来引用此 bean。 最后容器加 载 3 个 XML 文件来生成最终的 ApplicationContext。 在此情况下,可通过在配置文件中添加下

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n209" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;"><alias name="cornponentA" alias="comnponentB"/〉
<alias name="cornponentA” alias=”myApp" /></pre>

这样一来,每个组件及主程序就可通过唯一名字来引用同一个数据源而互不干扰 。

import的使用

对于 Spring 配置文件的编 写 , 我想,经历过庞大项目的人,都有那种恐惧的心理,太多的配置文件了 。 不过分模块是大多数人能想到的方法 , 但是 , 怎么分模块, 那就仁者见仁, 智者见智了。 使用 import是个好办法,例如我们可以构造这样的 Spring配置文件:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n224" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: initial initial; background-repeat: initial initial;">
<import resource="classpath:spring-dubbo-reference.xml"/>


<import resource="classpath:gateway-httprest-service.xml"/>


<import resource="classpath:spring-mq-container.xml"/>

<import resource="spring-property-dev-beans.xml"/></pre>

自定义标签使用

在很多情况下,我们需要为系统提供可配置化支持,简单的做法可以 直接基于 Spring 的标准 bean 来配置 ,但配置较为复杂或者需要更多丰富控制的时候,会显得非常笨拙 。一般的做法会用原生态的方式去解析定义好的 XML 文件,然后转化为配置对象。 这种方式当然可以解决所有问题,但实现起来 比较烦琐,特别是在配置非常复杂的时候,解析工作是一个不得不考虑的负担。 Spring提供了可扩展 Schema 的支持,这是一个不错的折中方案,扩展 Spring 自定义标签配置大致需要以下几个步骤(前提是要把 Spring 的 Core包加入项目中)。

  • 创 建一个需要扩展的组件 。

    首先我们创建一个普通的 POJO,这个 POJO 没有任何特别之处,只是用来接收配置文件。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n280" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">package test.customtag;
    @Data
    public class User {
    private String userName;
    private Str ing email;}
    ​</pre>

  • 定义一个 XSD 文件描述组件内容

    定义一个 XSD文件描述组件内容。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n292" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;"><?xml version="1.0” encoding=”UTF-8”?〉
    <schema xmlns=”http://www.w3.org/2001/XMLSchema
    targetNamespace=”http://www.lexueba.com/schema/user"
    xmlns:tns=”http://www.lexueba.com/schema/user
    elementFormDefault=”qualified”>
    <element name=”user ”>
    <complexType>
    <attribute name=”id” type=”string”/>
    <attribute name=”userName” type=”string”/>
    <attribute name=”email” type=”string”/>
    </complexType>
    </element>
    </schema ></pre>

    在上面的 XSD 文件中描述了一个新的 targetNamespace, 并在这个空间中定义了一个 name 为user的element, user有3个属性id、 userName和email,其中email的类型为string。 这3个类主要用于验证Spring配置文件中向定义格式。 XSD文件是XMLDTD的替代者,使用XML Schema

  • 创建一个文件,实现 BeanDefinitionParser 接口,用来解析 XSD 文件中的定义和组件定义。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n303" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">package test.custorntag;
    import org.Springfrarnework.beans.factory.support.BeanDefinitionBuilder;
    import org.Springfrarnework.beans.factory.xmlAbstractSingleBeanDefinitionParser;
    import org.Springfrarnework.util.StringUtils;
    import org.w3c.dorn.Elernent;
    //Element 对应的类
    class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    protected Class getBeanClass(Element element){
    return User.class
    }
    //从element中解析并提取对应的元索
    protected void doParse(Element element , BeanDefinitionBuilder bean){
    String userName = element.getAttribute(”userName”);
    String email =element.getAttribute (”email”);
    //将提取到的数据放入BeanDefinitionBuilder中,待到完成所有bean的解析后统一注册到BeanFactory中
    if (StringUtils.hasText(userName)) {
    bean.addPropertyValue(”userName”, userName); }
    if (StringUtils.hasText(email)) {
    bean.addPropertyValue(”email”, email);
    }
    }
    ​</pre>

  • 创建一个 Handler 文件,扩展自 NamespaceHandlerSupport,目的是将组件注册到 Spring容器。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n309" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">package test.customtag;
    import org.Springframework.beans.factory.xml.NamespaceHandlerSupport;
    public class MyNamespaceHandler extends NamespaceHandlerSupport {
    public void init() {
    registerBeanDefinitionParser("user",new UserBeanDefinitionParser());
    }
    }</pre>

    以上代码很简单, 无非是当遇到自定义标签<user:aaa这样类似于以 user开头的元素,就会把这个元素扔给对应的 UserBeanDefinitionParser去解析。

  • 编写 Spring.handlers 和 Spring.schemas 文件 。默认位置是在工程 的META-INF/文件夹下,当然,你可以通过 Spring 的扩展或者修改源码的方式改变路径 .

    Spring.handlers http: //www.lexueba.com/schema/user=test.customtag.MyNamespaceHandler

    Spring.schemas http://www.lexueba.com/schema/user.xsd=META-INF/Spring-test.xsd

    到这里自定义 的配置就结束了,而 Spring加载自定义的大致流程是遇到自定义标签然后就去 Spring.handlers 和 Spring.schemas 中去找对应的 handler 和 XSD,默认位置是/META-INF/下,进而有找到对应的 handler以及解析元素的 Parser,从而完成了整个自定义元素的解析,也就是说自己定义与 Spring 中默认的标准配置不同在于 Spring 将向定义标签解析的工作委托给了用户去实现 。

  • 创建测试配置文件,在配置文件中引入对应的命名空间以及XSD后,便可以直接使用自定义标签了 。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n352" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;"><beans xmlns=”http//:ww Springframework org/schema/beans”
    xmlns xsi=”http://www.w3.org/2001/XMLSchema-instance
    xmlns:myname=”http://www.lexueba.com/schema/user"
    xsi:schemaLocation=”http//www.Spriηgframework.org/schema/beans http://www.
    Springframework.org/schema/beans/Spring-beans-2.xsd
    http://www.lexueba.com/schema/user http://www.lexueba c。m/schema/user xsd">
    <myname:user id=”testbean” userName=”aaa” email=”bbb”/〉 </beans></pre>

  • 测试。

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n363" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">public static void main (String[] args) {
    ApplicationContext bf = new ClassPathXmlApplicationContext(”test/customtag/
    test.xml” ),
    User user= (User) bf.getBean (”testbean”);
    System.out println(user getUserName()+”,”+user.getSmail());}</pre>

    在上面的例子中,我们实现了通过 自定义标签实现了通过属性的方式将 user 类型的 Bean赋值,在 Spring中自定义标签非常常用 ,例如我们熟知 的事务标签 : tx(tx:annotation-driven)。

相关文章

网友评论

      本文标题:Spring XML中各种元素及属性的使用

      本文链接:https://www.haomeiwen.com/subject/zhgewhtx.html