在spring的配置文件中,可以添加自定义配置格式;
设我们需要自动下面的配置文件 application.xml;
-
<?xml version="1.0" encoding="UTF-8"?>
-
<spring:beans xmlns:spring=""
-
xmlns:xsi=""
-
xmlns="test.namespce"
-
xsi:schemaLocation=" /spring-beans.xsd
-
test.namespce x.xsd">
-
-
<test id="oneBean" serviceClass="Bean"/>
-
</spring:beans>
其目的自动生成 “com.test."+serviceClass的类; 该语句的命名空间是“test.namespce"; 注意xmlns
="test.namespce"; 对于其中test部分的格式校验,我们定义了x.xsd; 这个说明是在xsi:schemaLocation
=中(“其中记录了 namespace 和xsd文件对);
2. 添加自定义的x.xsd;
-
<?xml version="1.0" encoding="UTF-8"?>
-
<schema xmlns="" xmlns:tns="test.namespce" targetNamespace="test.namespce">
-
<element name="test" type="tns:testType"></element>
-
<complexType name="testType">
-
<attribute name="id" type="string"></attribute>
-
<attribute name="serviceClass" type="string"></attribute>
-
</complexType>
-
</schema>
3. 根据spring的需求,需要配置handlers。告诉系统当遇到
test.namespce命名空间的xml时,需要哪个类来处理;该文件位置为:META-INF/spring.handlers;其中记录:
-
test.namespce=com.test.spring.WjmNamespaceHandler
4. 编写com.test.spring.WjmNamespaceHandler
-
package com.test.spring;
-
-
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
-
-
public class WjmNamespaceHandler extends NamespaceHandlerSupport {
-
-
@Override
-
public void init() {
-
// TODO Auto-generated method stub
-
registerBeanDefinitionParser("test",new MyParser());
-
}
-
-
}
其中重载了一个init函数。该函数中记录,如果遇到test为root的element时,需要哪个类来处理;
5. 参见类
org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver,得到解析3的文件的方法getHandlerMappings;调用4的代码的函数请参见的resolve方法;注意开始是mapping中放置的是namespace和类名,被使用过一次后就被替换为实际类了。
6. 编写MyParser;
-
package com.test.spring;
-
-
import org.springframework.beans.factory.config.BeanDefinition;
-
import org.springframework.beans.factory.config.BeanDefinitionHolder;
-
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
-
import org.springframework.beans.factory.support.RootBeanDefinition;
-
import org.springframework.beans.factory.xml.BeanDefinitionParser;
-
import org.springframework.beans.factory.xml.ParserContext;
-
import org.w3c.dom.Element;
-
-
public class MyParser implements BeanDefinitionParser {
-
-
@Override
-
public BeanDefinition parse(Element element, ParserContext parserContext) {
-
// TODO Auto-generated method stub
-
RootBeanDefinition root = new RootBeanDefinition();
-
String class_name = element.getAttribute("serviceClass");
-
try {
-
-
Class bean_class = Class.forName("com.test." + class_name);
-
root.setBeanClass(bean_class);/* 设置需要创建的bean */
-
-
String id = element.getAttribute("id");
-
BeanDefinitionHolder idHolder = new BeanDefinitionHolder(root, id);
-
BeanDefinitionReaderUtils.registerBeanDefinition(idHolder, parserContext.getRegistry());/*这样getBean就可以获得对象了*/
-
} catch (ClassNotFoundException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
return root;
-
}
-
}
参见org.springframework.beans.factory.xml.
NamespaceHandlerSupport类的parse方法看到相关调用;
7. 写一个简单的Bean类:
-
package com.test;
-
-
public class Bean {
-
String name;
-
-
public String getName() {
-
return "hello";
-
}
-
-
public void setName(String name) {
-
this.name = name;
-
}
-
-
}
8. 最终实现main函数;
-
package com.test.Main;
-
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-
import com.test.Bean;
-
-
public class Main {
-
public static void main(String []args){
-
ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
-
Bean tag = (Bean) ctx.getBean("oneBean");
-
System.out.println("oneBean age is " + tag.getName());
-
}
-
}
阅读(3941) | 评论(0) | 转发(1) |