spring模仿dubbo自定义schema解析并注入容器
Posted 醉酒的小男人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring模仿dubbo自定义schema解析并注入容器相关的知识,希望对你有一定的参考价值。
dubbo里边有很多如provider、consumer、registry的配置都是通过spring自定义Schema来实现的,模仿写一个demo来加深记忆。
步骤如下
- 编写定义
java bean
- 编写
xsd
配置文件 - 编写
spring.handlers
和spring.schemas
- 编写
myschema.xml
- 编写
NamespaceHandler和BeanDefinitionParser
代码案例
本地代码结构
定义java bean
package myschema.model;
public class User {
private String id;
private String name;
private String sex;
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
编写resources/META-INF/user.xsd文件
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<xsd:schema xmlns="http://www.orchome.com/eric-lin/schema/user"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
targetNamespace="http://www.orchome.com/eric-lin/schema/user">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:element name="user">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="name" type="xsd:string">
<xsd:annotation>
<xsd:documentation>姓名</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="sex" type="xsd:string">
<xsd:annotation>
<xsd:documentation>性别</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="age" type="xsd:int">
<xsd:annotation>
<xsd:documentation>年龄</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
resources/META-INF/spring.schemas 文件内容
http\\://www.orchome.com/eric-lin/schema/user=myschema.UserNamespaceHandler
resources/META-INF/spring.handlers 文件内容
http\\://www.orchome.com/eric-lin/schema/user/user.xsd=META-INF/user.xsd
myschema.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:test="http://www.orchome.com/eric-lin/schema/user"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.orchome.com/eric-lin/schema/user
http://www.orchome.com/eric-lin/schema/user/user.xsd">
<test:user id="test1" name="张三" sex="男" age="30" />
</beans>
NamespaceHandler
package myschema;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class UserNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
//registerBeanDefinitionParser("user",new DubboBeanDefinitionParser());
registerBeanDefinitionParser("user",new UserBeanDefinitionParser());
}
}
继承AbstractSingleBeanDefinitionParser
package myschema;
import myschema.model.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.w3c.dom.Element;
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return User.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder bean) {
String id = element.getAttribute("id");
String name = element.getAttribute("name");
String sex = element.getAttribute("sex");
int age = Integer.parseInt(element.getAttribute("age"));
bean.addPropertyValue("id",id);
bean.addPropertyValue("name", name);
System.out.println("==========================第一种方式继承AbstractSingleBeanDefinitionParser=========================================");
bean.addPropertyValue("sex", sex);
bean.addPropertyValue("age", age);
}
}
另外一种方式也可以实现BeanDefinitionParser
package myschema;
import myschema.model.User;
import org.springframework.beans.factory.config.BeanDefinition;
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 DubboBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(User.class);
beanDefinition.setLazyInit(false);
String id = element.getAttribute("id");
String name = element.getAttribute("name");
String sex = element.getAttribute("sex");
int age = Integer.parseInt(element.getAttribute("age"));
System.out.println("==========================第二种方式实现BeanDefinitionParser=========================================");
beanDefinition.getPropertyValues().addPropertyValue("id", id);
beanDefinition.getPropertyValues().addPropertyValue("name", name);
beanDefinition.getPropertyValues().addPropertyValue("sex", sex);
beanDefinition.getPropertyValues().addPropertyValue("age", age);
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
return beanDefinition;
}
}
测试类
package myschema;
import myschema.model.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSchema {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:myschema.xml");
User test1 = (User) context.getBean("test1");
System.out.println(test1.getId());
System.out.println(test1.getName());
System.out.println(test1.getSex());
System.out.println(test1.getAge());
}
}
结果
以上是关于spring模仿dubbo自定义schema解析并注入容器的主要内容,如果未能解决你的问题,请参考以下文章