spring2自定義標籤

iteye_6308發表於2009-03-19

頭很大啊.現在需要擴充套件mule的標籤.

只得先從spring的標籤擴充套件開始, 並筆記之:

 

spring2以上版本支援自定義標籤.
作為一般的應用程式開發人員,擴充套件spring的標籤意義不大。
但如果你是一個平臺開發人員,則很有必要擁有一套自己的標籤, 提供給應用開發人員使用.
由於mule的標籤是基於spring的xml schema擴充套件的, 為了弄出mule的自定義標籤,讓我們從一個簡單的spring標籤製作開始吧。
我需要做的標籤如下:

<co:log id="myLog" isPrintTime="true" company="cb" />

 

這個標籤功能簡單, 僅僅列印一下log.它和如下spring bean功能一樣:

    <bean id="log" class="com.log.LogBean">


        <constructor-arg value="true"></constructor-arg>


        <property name="company" value="cb"></property>


    </bean>

 
標籤的schema如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.springframework.org/schema/myns"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:beans="http://www.springframework.org/schema/beans"
    targetNamespace="http://www.mycompany.com/schema/myns"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified">

   <xsd:import namespace="http://www.springframework.org/schema/beans"/>
  
   <xsd:element name="log">
      <xsd:complexType>
         <xsd:complexContent>
            <xsd:extension base="beans:identifiedType">
               <xsd:attribute name="isPrintTime" type="xsd:boolean" use="required"/>
               <xsd:attribute name="company" type="xsd:string"/>
            </xsd:extension>
         </xsd:complexContent>
      </xsd:complexType>
   </xsd:element>  
</xsd:schema>
 



log標籤背後的bean如下:

public class LogBean
{
    private boolean isPrintTiem = false;
   
    private String company = "";
   
    public LogBean(boolean isPrintTime)
    {
        this.isPrintTiem = isPrintTime;
    }
   
    public void print(String log)
    {
        if(this.isPrintTiem)
            System.out.println(this.company + new Date() + ":"  + log);
        else
            System.out.println(this.company + ":" + log);
    }

    public String getCompany()
    {
        return company;
    }

    public void setCompany(String company)
    {
        this.company = company;
    }

    public boolean isPrintTiem()
    {
        return isPrintTiem;
    }
}

 


實現一個標籤需要擴充套件一個class:
NamespaceHandlerSupport

並實現一個interface:

BeanDefinitionParser

public class LogNamespaceHandler extends NamespaceHandlerSupport
{
   
    public void init()
    {
        registerBeanDefinitionParser("log",
                new LogBeanDefinitionParser());       
    }
}

 


LogNamespaceHandler在spring的Ioc容器載入配置檔案時,遇到log節點便會呼叫LogBeanDefinitionParser,完成bean的初始化,並註冊到spring context中.

public class LogBeanDefinitionParser implements
        BeanDefinitionParser {

    public BeanDefinition parse(Element element, ParserContext parserContext) {

        // create a RootBeanDefinition that will serve as configuration
        // holder for the 'pattern' attribute and the 'lenient' attribute
        RootBeanDefinition beanDef = new RootBeanDefinition();
        beanDef.setBeanClass(LogBean.class);

        // never null since the schema requires it
        String pattern = element.getAttribute("isPrintTime");
        beanDef.getConstructorArgumentValues().addGenericArgumentValue(pattern);
        String company = element.getAttribute("company");
        if(StringUtils.hasText(company))
        {
            beanDef.getPropertyValues().addPropertyValue("company",company);
        }

        // retrieve the ID attribute that will serve as the bean identifier in
        // the context
        String id = element.getAttribute("id");

        // create a bean definition holder to be able to register the
        // bean definition with the bean definition registry
        // (obtained through the ParserContext)
        BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDef, id);

        // register the BeanDefinitionHolder (which contains the bean
        // definition)
        // with the BeanDefinitionRegistry
        BeanDefinitionReaderUtils.registerBeanDefinition(holder, parserContext
                .getRegistry());

        return beanDef;

    }

}

 
最後在META_INF中, 加入兩個配置檔案:
spring.handlers和spring.schemas
spring.handlers內容如下:

http\://www.mycompany.com/schema/myns=com.log.LogNamespaceHandler

 

spring.schemas內容如下:

http\://www.mycompany.com/schema/myns/myns.xsd=com/log/logns.xsd

 
最後測試一下:
新建一個applicationContext.xml:

<?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:co="http://www.mycompany.com/schema/myns"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.mycompany.com/schema/myns http://www.mycompany.com/schema/myns/myns.xsd
    ">
    <co:log id="myLog" isPrintTime="true" company="cb" />
   
    <bean id="log" class="com.log.LogBean">
        <constructor-arg value="true"></constructor-arg>
        <property name="company" value="cb"></property>
    </bean>
</beans>

 
testcase:

public class LogTagTest extends AbstractDependencyInjectionSpringContextTests
{
    protected String[] getConfigLocations()
    {
        return new String[] {"classpath*:applicationContext*.xml"};
    }
   
    public void testLogBean()
    {
        LogBean logBean = (LogBean)this.applicationContext.getBean("myLog");
        assertTrue(StringUtils.hasText(logBean.getCompany()));
        assertTrue(logBean.isPrintTiem());
        logBean.print("is fun!");
       
    }
}
 


綠色在期待中出現.

為了讓mule使用這個bean, 只需mule的配置檔案匯入上面的spring的Application.xml

   
    <spring:beans>
        <spring:import resource="applicationContext.xml" />
    </spring:beans>

 
然後定義一個mule:

    <model name="LogModel">
        <service name="databaseCommonUMO">
            <!-- any number of endpoints can be added to an inbound router -->
            <inbound>
                <vm:inbound-endpoint path="logQueue" />
            </inbound>
            <component>
                <method-entry-point-resolver>
                    <include-entry-point method="print" />
                </method-entry-point-resolver>
                <spring-object bean="iplatformLog"></spring-object>
            </component>
        </service>
    </model>
</mule>

 


寫一個mule的測試:

public class MySpringTagMuleClientTest
{
    public static void main(String[] args) throws MuleException
    {
        // create mule
        MuleContext muleContext;
        String config = "mule-myspringtag-config.xml";
        muleContext = new DefaultMuleContextFactory().createMuleContext(config);
        muleContext.start();
        // creat mule client
        MuleClient client = new MuleClient();
        MuleMessage response = client.send("vm://logQueue", "hello, I'm log content.", null);       
    }

}

 控制檯列印出如下訊息:

cyberThu Mar 19 16:59:26 CST 2009:hello, I'm log content.
 

 

相關文章