Spring自定义标签扩展

发表时间:2017-09-19 14:38:23 浏览量( 63 ) 留言数( 0 )

学习目标:

1、了解Spring自定义扩展配置


学习过程:

一、自定一Scheme文件,这个在我们之前也讲过了,但是这里要注意的是我们需要继承Spring的beans。代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.javadayup.org/mytag" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:beans="http://www.springframework.org/schema/beans"
	targetNamespace="http://www.javadayup.org/mytag" elementFormDefault="qualified"
	attributeFormDefault="unqualified">
	<!--这里需要注意引入-->
	<xsd:import namespace="http://www.springframework.org/schema/beans"
		schemaLocation="http://www.springframework.org/schema/beans/spring-beans-4.3.xsd" />
	<xsd:element name="register">
		<xsd:complexType>
			<xsd:complexContent>
			         <!--继承-->
				<xsd:extension base="beans:identifiedType">
					<xsd:attribute name="ip" type="xsd:string" />
					<xsd:attribute name="port" type="xsd:string" />
					<xsd:attribute name="interfaceName" type="xsd:string" />
				</xsd:extension>
			</xsd:complexContent>
		</xsd:complexType>
	</xsd:element>

</xsd:schema>


二、定义解析类

1、定义需要Bean。

public class MyTagBean implements  InitializingBean, DisposableBean {

	private String ip;
	private String port;
	private String interfaceName;


	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getPort() {
		return port;
	}

	public void setPort(String port) {
		this.port = port;
	}

	public String getInterfaceName() {
		return interfaceName;
	}

	public void setInterfaceName(String interfaceName) {
		this.interfaceName = interfaceName;
	}


	public void destroy() throws Exception {
		// TODO Auto-generated method stub

	}

	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub

	}

	// 可以代理了spring的原来的对象
//	public Object getObject() throws Exception {
//		// TODO Auto-generated method stub
//		return null;
//	}

	public Class getObjectType() {
		try {
			return this.getClass().getClassLoader().loadClass(interfaceName);
		} catch (ClassNotFoundException e) {
			System.err.println("spring analyze fail!");
		}
		return null;
	}

	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return false;
	}

}

2、定义解析类

public class MyTagBeanDefinitionParser implements BeanDefinitionParser {

	public BeanDefinition parse(Element element, ParserContext parserContext) {
		String interfaceName = element.getAttribute("interfaceName");
		String id = element.getAttribute("id");
		String port = element.getAttribute("port");
		String ip = element.getAttribute("ip");

		RootBeanDefinition beanDefinition = new RootBeanDefinition();
		beanDefinition.setBeanClass(MyTagBean.class);
		beanDefinition.setLazyInit(false);

		beanDefinition.getPropertyValues().addPropertyValue("interfaceName", interfaceName);
		beanDefinition.getPropertyValues().addPropertyValue("ip", ip);
		beanDefinition.getPropertyValues().addPropertyValue("port", port);

		parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
		return beanDefinition;
	}

}

3、定义注册类

public class MyTagNamespaceHandlerSupport  extends NamespaceHandlerSupport  {

	public void init() {
		 registerBeanDefinitionParser("register",   new MyTagBeanDefinitionParser());  
		 
		 //可以注册多个
		// registerBeanDefinitionParser("myTag2",  new MyTagBeanDefinitionParser2());  
		 
	}

}

三、按照Spring的规范定义说明文件:

配置schema和handler

Spring没那么聪明,它无法知道我们在什么地方定义了哪些扩展标签,这些标签将被谁解析,怎么解析。这个过程要我们通过一些配置文件来告知Spring知道,它们就是spring.handlers和spring.schemas,它们放在META-INF目录中。Spring.jar的META-INF目录中也有同名的文件,它们的文件内容基本上是相似的,而Spring在执行过程中,如果发现其他jar文件的META-INF文件夹中包含有这两个文件,Spring将会合并它们。


spring.handlers内容如下:

   http\://www.javadayup.org/mytag=org.springday10.springexclude.MyTagNamespaceHandlerSupport

spring.schemas内容如下:

 http\://www.javadayup.org/mytag/mytag.xsd=META-INF/mytag.xsd

最后项目结构如下:

attcontent/395ae857-4fd5-4abb-b67a-669765503419.png


四、可以使用了。

1、定义

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:mytag="http://www.javadayup.org/mytag"

xsi:schemaLocation="

        http://www.springframework.org/schema/beans 

        http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context.xsd

        http://www.javadayup.org/mytag

        http://www.javadayup.org/mytag/mytag.xsd">


<mytag:register ip="mytag"  interfaceName="asdf" port="8080" id="mytag" />


</beans>

2、测试

public class RunTest {
	
	public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");

        MyTagBean manage = (MyTagBean) context.getBean("mytag");
        System.out.println(manage);
	}

}