写在前面: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无缝集成?