寫在前面:java
你們下載spring源碼的話再test項目中會有一個示例Demo.這裏我是仿照demo,寫的一個簡單的例子,事實上官網給的demo寫的更爲複雜,是對象裏面包含List變量的.同時參考了《Spring源碼深度解析》一書第4章內容,在此聲明。spring
1.定義一個普通的POJO,也就是未來咱們要在spring配置文件裏面要注入的beanexpress
/** * * @author zhouplus * @since 5.0 */ public class User { private String name; private String age; //getter and setter }
2.定義一個XSD文件描述組件內容apache
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <xsd:schema xmlns="http://www.zhou.com/schema/user" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.zhou.com/schema/user" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:element name="user"> <xsd:complexType> <xsd:attribute name="id" type="xsd:ID"/> <xsd:attribute name="name" use="required" type="xsd:string"/> <xsd:attribute name="age" use="required" type="xsd:string"/> </xsd:complexType> </xsd:element> </xsd:schema>
3.建立一個文件,實現BeanDefinitionParser接口,這裏繼承自AbstractBeanDefinitionParserapp
/* * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zhou; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** * * @author zhouplus * @since 5.0 */ public class UserBeanDefinitionParser extends AbstractBeanDefinitionParser { /* (non-Javadoc) * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext) */ @Override protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { return parseUserElement(element); } private static AbstractBeanDefinition parseUserElement(Element element) { BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(UserFactoryBean.class); factory.addPropertyValue("user", parseUser(element)); return factory.getBeanDefinition(); } private static BeanDefinition parseUser(Element element) { BeanDefinitionBuilder component = BeanDefinitionBuilder.rootBeanDefinition(User.class); component.addPropertyValue("name", element.getAttribute("name")); component.addPropertyValue("age", element.getAttribute("age")); return component.getBeanDefinition(); } }
4.建立一個Handler文件,擴展自NamespaceHandlerSupport,目的是將組件註冊到spring容器less
/* * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zhou; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; /** * * @author zhouplus * @since 5.0 */ public class MyNamespaceHandler extends NamespaceHandlerSupport { /* (non-Javadoc) * @see org.springframework.beans.factory.xml.NamespaceHandler#init() */ @Override public void init() { registerBeanDefinitionParser("user", new UserBeanDefinitionParser()); } }
5.編寫Spring.handlers 和Spring.schemes文件,默認位置是在工程的/META-INF/文件夾下,固然,你能夠經過Spring的擴展或者修改源碼的方式修改路徑。dom
Spring.handlers內容:ide
http\://www.zhou.com/schema/user=com.zhou.MyNamespaceHandler單元測試
Spring.schemes內容:測試
http\://www.zhou.com/schema/user/user.xsd=com/zhou/user.xsd
6.建立配置文件user-config.xml在配置文件中引入對應的命名空間以及XSD後,即可以直接使用自定義標籤了。
<?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:zhou="http://www.zhou.com/schema/user" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.zhou.com/schema/user http://www.zhou.com/schema/user/user.xsd"> <zhou:user id="testbean" name="zhangsan" age="18" /> </beans>
7.測試,這裏簡單使用main方法測試,寫更多測試的話建議使用Junit單元測試。
/* * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zhou; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * * @author zhouplus * @since 5.0 */ public class MyMain { public static void main(String[] args) { System.out.println("進入main"); ApplicationContext bf = new ClassPathXmlApplicationContext("com/zhou/user-config.xml"); System.out.println("Application初始化完成"); User user = (User) bf.getBean("testbean"); System.out.println(user.getName() + "," + user.getAge()); } }
8.測試結果
結語:
上面的例子中,咱們實現了經過自定義標籤實現了經過了屬性的方式將user類型的Bean賦值,在Spring中自定義標籤分廠經常使用,例如咱們熟知的事物標籤:tx(<tx:annotation-driven>)
看到這裏是否想倒能夠把你本身寫的組件和spring無縫集成?