1:前に書く
Springはデフォルトでタグ、一般的に使用されるBeanタグ、プロパティ、コンストラクター引数などを提供します。Springではタグをカスタマイズすることもできます。
2:デフォルトラベルの解析プロセス
ここでは、xsd
簡単に説明する例として制約ファイルを取り上げます。最初にxsd制約ファイルが必要であり、次に名前空間とxsdファイル間の対応を説明するためにspring.schemaファイルが必要です。これらは次の場合にも必要です。タグのカスタマイズ。カスタムラベルに加えて、解析クラスも必要なので、そのようなクラスも必要です。春には、このクラスでorg.springframework.beans.factory.xml.NamespaceHandler
インターフェイスを実装する必要があります。実際、継承する必要があるのはorg.springframework.beans.factory.xml.NamespaceHandlerSupport
抽象サブクラスだけです。。これらを1つずつ実装してみましょう必须条件
。
3:例
3.1:例
カスタムタグは、タグbean
の役割を実現します。つまり、春の豆を作成する作業を完了します。
3.2:xsd制約ファイルを定義する
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://dongshi.daddy.com/schema/ok"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://dongshi.daddy.com/schema/ok"
elementFormDefault="qualified">
<!-- 定义service顶层标签,其类型是复杂类型server -->
<xsd:element name="service" type="server">
<xsd:annotation>
<xsd:documentation><![CDATA[ The service config ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- 定义server类型可以有哪些属性 -->
<xsd:complexType name="server">
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The unique identifier for a bean. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="serverName" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The name of the bean. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:schema>
この式の意味は、serviceタグにid属性とserverName属性を含めることができるということです。最後に、ファイルをresources
リソースファイルディレクトリに置き、ファイルに名前を付けますdongshidaddy-1.0.xsd
。これは、後続の構成で使用されます。その中にtargetNamespace="http://dongshi.daddy.com/schema/ok"
は、制約ファイルの名前空間を設定することがありますhttp://dongshi.daddy.com/schema/ok
。
3.3:xsd制約ファイルを構成する
spring.schemas
で構成する必要があり、ファイルをクラスパスのMETA-INF
下のフォルダーに配置する必要があるため、最初にリソースの下でフォルダーを定義する必要があります。定義内容は次のとおりです。
http\://dongshi.daddy.com/schema/ok/ok-1.0.xsd=./dongshidaddy-1.0.xsd
3.4:カスタムタグを解析するクラスを定義します
インターフェイスの実装に注意してくださいorg.springframework.beans.factory.xml.BeanDefinitionParser
、メインコードはコメントされています:
public class CommonNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
this.registerBeanDefinitionParser("service",
new OkServerDefinitionParser(ServerBean.class));
}
}
OkServerDefinitionParser:
public class OkServerDefinitionParser implements BeanDefinitionParser {
private final Class<?> clazz;
private static final String default_prefix = "ok-";
private static final AtomicLong COUNT = new AtomicLong(0);
public OkServerDefinitionParser(Class<?> clazz) {
this.clazz = clazz;
}
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
return parseHelper(element, parserContext, this.clazz);
}
private BeanDefinition parseHelper(Element element, ParserContext parserContext, Class<?> clazz) {
// 创建封装信息的beandefinition
RootBeanDefinition bd = new RootBeanDefinition();
// 不延迟加载
bd.setLazyInit(false);
String id = element.getAttribute("id");
if (id == null || id.isEmpty()) {
id = default_prefix + COUNT.getAndDecrement();
}
// 获取配置的serverName的值
String serverName = element.getAttribute("serverName");
// 设置class
bd.setBeanClass(clazz);
// 设置初始化方法的名称
bd.setInitMethodName("init");
// 从beandefinition中获取存储属性名称->属性值新的对象
MutablePropertyValues propertyValues = bd.getPropertyValues();
// 添加serverName属性和其值到可修改属性值对象中
propertyValues.addPropertyValue("serverName", serverName);
// 通过注册机注册BeanDefinition信息,最终会存储到一个map中,key就是id,value就是BeanDefinition
parserContext.getRegistry().registerBeanDefinition(id, bd);
// 返回创建的BeanDefinition,后续spring就会使用这个BeanDefinition对象来创建spring bean了
return bd;
}
}
ServerBean:
public class ServerBean {
private String serverName;
//init method
public void init() {
System.out.println("bean ServerBean init.");
}
@Override
public String toString() {
return "[Service]=>" + serverName;
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
}
3.5:解析クラスを登録します
でMETA-INF
ケースファイルの作成spring.handlers
次のように、ファイルを:
http\://dongshi.daddy.com/schema/ok=yudaosourcecode.selfdefinetag.CommonNamespaceHandler
名前空間の場合http\://dongshi.daddy.com/schema/ok
、解決クラスが使用されることを意味しますyudaosourcecode.selfdefinetag.CommonNamespaceHandler
3.6: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:ok="http://dongshi.daddy.com/schema/ok"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://dongshi.daddy.com/schema/ok
http://dongshi.daddy.com/schema/ok/dongshidaddy-1.0.xsd">
<ok:service id="testServer" serverName="HelloWorldService"/>
</beans>
xmlns:ok="http://dongshi.daddy.com/schema/ok"
名前空間が定義されているhttp://dongshi.daddy.com/schema/ok
接頭辞を使用して<ok:
、およびxsi:schemaLocation
制約ファイルの場所は、それに宣言されています。
3.7:テストコード
@Test
public voidtestSelfDefineTag() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("testselfdefinetag.xml");
ServerBean testServer = ac.getBean("testServer", ServerBean.class);
System.out.println(testServer);
}
実行:
bean ServerBean init.
[Service]=>HelloWorldService
Process finished with exit code 0