相信,大多数小伙伴们仔细阅读了上篇文章并翻阅了Dubbo的部分代码,一定会对其有一个大体的了解吧。
当然,不了解也没问题,反正不是我不想让你不了解。好了,言归正传,今天呢,与大家分享的主题如题目所述《如何自定义Schema》。
项目大体如下(请自行忽略报错和它的丑):
小伙伴们,有么有发现跟上一篇的结构其实是差不多的,唯一的差别是,这个只是个demo。
定义一个类,ServiceConfig:
public class ServiceConfig {
private String interfaceVal;
private Object ref;
public ServiceConfig() {
super();
}
public ServiceConfig(String interfaceVal, Object ref) {
super();
this.interfaceVal = interfaceVal;
this.ref = ref;
}
public String getInterfaceVal() {
return interfaceVal;
}
public void setInterfaceVal(String interfaceVal) {
this.interfaceVal = interfaceVal;
}
public Object getRef() {
return ref;
}
public void setRef(Object ref) {
this.ref = ref;
}
}
定义一个人 PeopleConfig:
public class PeopleConfig {
private String name;
private String sex;
private Integer age;
public PeopleConfig() {
super();
}
public PeopleConfig(String name, String sex, Integer age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
处理器 RpcBeanDefinitionParser:
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.w3c.dom.Element;
import com.itstyle.rpc.cinfig.PeopleConfig;
import com.itstyle.rpc.cinfig.ServiceConfig;
public class RpcBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
private Class<?> beanClass;
public RpcBeanDefinitionParser(Class<?> beanClass) {
this.beanClass = beanClass;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
protected Class getBeanClass(Element element) {
return this.beanClass;
}
protected void doParse(Element element, BeanDefinitionBuilder bean) {
if (ServiceConfig.class.equals(this.beanClass)) {
String interfaceVal = element.getAttribute("interface");
String refVal = element.getAttribute("ref");
Object reference = new RuntimeBeanReference(refVal);
bean.addPropertyValue("interfaceVal", interfaceVal);
bean.addPropertyValue("ref", reference);
}else if(PeopleConfig.class.equals(this.beanClass)){
String name = element.getAttribute("name");
String sex = element.getAttribute("sex");
String age = element.getAttribute("age");
bean.addPropertyValue("name", name);
bean.addPropertyValue("sex", sex);
bean.addPropertyValue("age", age);
}
}
}
控制器 RpcNamespaceHandler:
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import com.itstyle.rpc.cinfig.PeopleConfig;
import com.itstyle.rpc.cinfig.ServiceConfig;
public class RpcNamespaceHandler extends NamespaceHandlerSupport {
//初始化配置
public void init() {
registerBeanDefinitionParser("service", new RpcBeanDefinitionParser(ServiceConfig.class));
registerBeanDefinitionParser("people", new RpcBeanDefinitionParser(PeopleConfig.class));
}
}
当然,这里我还建了一个service:
public interface IBeanService {
String say();
}
public class BeanServiceImpl implements IBeanService {
@Override
public String say() {
return "科帮网欢迎你";
}
}
好了,接下来就开始我们的配置吧:
spring.schemas:
http\://code.itstyle.com/schema/itstyle/itstyle.xsd=META-INF/itstyle.xsd
spring.handlers:
http\://code.itstyle.com/schema/itstyle=com.itstyle.rpc.cinfig.spring.schema.RpcNamespaceHandler
itstyle.xsd:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://code.itstyle.com/schema/itstyle"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://code.itstyle.com/schema/itstyle">
<!-- 向一个文档添加带有不同目标命名空间的多个 schema -->
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
<xsd:complexType name="serviceType">
<xsd:complexContent>
<xsd:extension base="beans:identifiedType" >
<xsd:attribute name="interface" type="xsd:string" />
<xsd:attribute name="ref" type="xsd:string" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="service" type="serviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[ The annotation config ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:complexType name="peopleType">
<xsd:complexContent>
<xsd:extension base="beans:identifiedType" >
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="sex" type="xsd:string" />
<xsd:attribute name="age" type="xsd:string" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="people" type="peopleType">
<xsd:annotation>
<xsd:documentation><![CDATA[ The annotation config ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:schema>
spring-itstyle.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:itstyle="http://code.itstyle.com/schema/itstyle"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.itstyle.com/schema/itstyle
http://code.itstyle.com/schema/itstyle/itstyle.xsd
">
<bean id="say" class="com.itstyle.rpc.service.impl.BeanServiceImpl"></bean>
<itstyle:service id="service" interface="com.itstyle.rpc.service.IBeanService" ref="say"/>
<itstyle:people id="xiaoming" name="小明" sex="男" age="10"/>
</beans>
好了,最后我们写一个测试ItstyleSchema:
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itstyle.rpc.cinfig.PeopleConfig;
import com.itstyle.rpc.cinfig.ServiceConfig;
import com.itstyle.rpc.service.IBeanService;
public class ItstyleSchema {
@SuppressWarnings("resource")
@Test
public void test() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"classpath:spring-itstyle.xml");
context.start();
//服务接口
ServiceConfig service = (ServiceConfig) context.getBean("service");
IBeanService service1 = (IBeanService) service.getRef();
//实现方法
System.out.println(service1.say());
//xiaoming
PeopleConfig people = (PeopleConfig) context.getBean("xiaoming");
System.out.println("我是:"+people.getName());
}
}