推荐直接看第三篇文章和后面的参考文献。
=============================================================================
spring 自定义标签 学习 http://blog.csdn.net/ruishenh/article/details/33741501
例子不错,可以看看。
=============================================================================
Spring自定义标签 http://zhangxing119.iteye.com/blog/1796906
Spring自定义标签的原理
XML通常通过DTD、XSD定义,但DTD的表达能力较弱,XSD定义则能力比较强,能够定义类型,出现次数等。自定义标签需要XSD支持,在实现时使用Namespace扩展来支持自定义标签。
当你在苦逼的写下面的代码时:
- <bean id="beanId" class="com.xxx.xxxx.Xxxxx">
- <property name="property1">
- <value>XXXX</value>
- </property>
- <property name="property2">
- <value>XXXX</value>
- </property>
- </bean>
是不是会羡慕这样写代码呢?
- <xxx:xxxx id="beanId"/>
Spring通过XML解析程序将其解析为DOM树,通过NamespaceHandler指定对应的Namespace的BeanDefinitionParser将其转换成BeanDefinition。再通过Spring自身的功能对BeanDefinition实例化对象。
在期间,Spring还会加载两项资料:
-
META-INF/spring.handlers
指定NamespaceHandler(实现org.springframework.beans.factory.xml.NamespaceHandler)接口,或使用org.springframework.beans.factory.xml.NamespaceHandlerSupport的子类。 -
META-INF/spring.schemas
在解析XML文件时将XSD重定向到本地文件,避免在解析XML文件时需要上网下载XSD文件。通过现实org.xml.sax.EntityResolver接口来实现该功能。
=============================================================================
自定义Spring配置标签 http://blog.csdn.net/bingduanlbd/article/details/38770685
引言:
在Sping中,一般使用<bean>这样的元素来配置一个bean,Spring在创建容器的时候会扫描这些配置,根据配置创建对象存放于容器中,然后我们再从容器中取出,或者在配置其他bean的时候作为属性注入。使用bean配置的一个限制是我们必须遵循配置文件的XML Schema定义,这在大多数情况下不会出现问题。但是在一些情况下,我们希望实现更为灵活的bean配置。Spring为此提供了 Custom tag Support,也称为Extensible XML Authoring。通过这个拓展点,我们可以灵活定制自己需要的配置格式。
例如,如果我们使用了责任链设计应用程序,那么我们可能希望用下面的方式来配置责任链:
- <chain id="orderChain" class="foo.bar">
- <handler> handler1</handler>
- <hadnler> handler2</handler>
- </chain>
档Spring创建容器时,扫描到这样的元素的时候,会根据我们事先的定义实例化一个责任链对象,并填充属性。因此,这种特殊的<chain>标签可以作为<bean>标签以外的另一种形式。借助Spring的Custome Tag,我们完全可以实现这样的bean配置。在产品级的应用框架中,可以实现更为复杂的定制标签元素。作为一个入门级别的介绍,我们定义一个用于配置日期格式化的一个类SimpleDateFormat。当然,使用传统的<bean>完全够用,我们这里只是作为例子。
一个HelloWorld例子:
定制标签的第一步是要定义标签元素的XML结构,也就是采用XSD来元素我们要定制的元素的结构时怎样的。我们定义如下一个简单的XSD:
- <?xml version="1.0" encoding="UTF-8"?>
- <xsd:schema xmlns="http://www.mycompany.com/schema/myns"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:beans="http://www.springframework.org/schema/beans"
- targetNamespace="http://www.mycompany.com/schema/myns"
- elementFormDefault="qualified"
- attributeFormDefault="unqualified">
- <xsd:import namespace="http://www.springframework.org/schema/beans"/>
- <xsd:element name="dateformat">
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="beans:identifiedType">
- <xsd:attribute name="lenient" type="xsd:boolean"/>
- <xsd:attribute name="pattern" type="xsd:string" use="required"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
在这个XSD定义中,有一个标签叫dateformat,这就是我们用来替换bean标签的自定义标签。注意到我们导入了Spring本身的beans命名空间,并且在beans:identifiedType基础之上定义dateformat标签。也就是我们这个标签可以像<bean>标签一样拥有id属性。同时我们增加了两个属性lenient和pattern。这有点继承的味道。
定义完XSD之后,我们要告诉Spring遇到这样的标记(命名空间+元素名称)时,如何创建对象。Spring中,完成这个任务的是NamespaceHandler。因此我们需要提供一个NamespaceHandler实现来处理自定义的<dateformat>标签元素。一个简单的实现如下:
- package extensiblexml.customtag;
- import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
- public class MyNamespaceHandler extends NamespaceHandlerSupport {
- public void init() {
- registerBeanDefinitionParser("dateformat",
- new SimpleDateFormatBeanDefinitionParser());
- }
- }
我们在初始化方法中注册了一个Bean定义的解析器,这个解析器就是用来解析定制的配置标签的。其实现如下:
- package extensiblexml.customtag;
- import org.springframework.beans.factory.support.BeanDefinitionBuilder;
- import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
- import org.springframework.util.StringUtils;
- import org.w3c.dom.Element;
- import java.text.SimpleDateFormat;
- public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
- protected Class<SimpleDateFormat> getBeanClass(Element element) {
- return SimpleDateFormat.class;
- }
- @SuppressWarnings("deprecation")
- protected void doParse(Element element, BeanDefinitionBuilder bean) {
- // this will never be null since the schema explicitly requires that a value be supplied
- String pattern = element.getAttribute("pattern");
- bean.addConstructorArg(pattern);
- // this however is an optional property
- String lenient = element.getAttribute("lenient");
- if (StringUtils.hasText(lenient)) {
- bean.addPropertyValue("lenient", Boolean.valueOf(lenient));
- }
- }
- }
这个解析器的doParse中,实现了解析的具体逻辑,借助Spring提供的支持类,我们可以很轻松地完成解析。以上三个文件放在同一个目录下,即把XSD文件跟Java代码放在同一目录。编码完毕之后,还需要做一些配置工作。我们必须告诉Spring我们准备使用自定义的标签元素,告诉Spring如何解析元素,否则Spring没那么聪明。这里需要2个配置文件,在与代码根路径同一级别下,床垫一个叫META-INF的文件。并在里面创建名为spring.handlers和spring.schemas,用于告诉Spring自定义标签的文档结构以及解析它的类。两个文件内容分别如下:
spring.handlers:
- http\://www.mycompany.com/schema/myns=extensiblexml.customtag.MyNamespaceHandler
等号的左边是XSD定义中的targetNamespace属性,右边是NamespaceHandler的全称限定名。
spring.schemas:
- http\://www.mycompany.com/schema/myns/myns.xsd=extensiblexml/customtag/myns.xsd
然后像往常一样配置bean,作为简单的测试,我们定义一个bean:
- <?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:myns="http://www.mycompany.com/schema/myns"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.mycompany.com/schema/myns http://www.mycompany.com/schema/myns/myns.xsd" >
- <myns:dateformat id="defaultDateFormat" pattern="yyyy-MM-dd HH:mm"
- lenient="true" />
- </beans>
在Eclipse中,整个项目结构如下图:
最后我们写个测试类测试一下能否工作:
- package extensiblexml.customtag;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class Test {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext(
- "beans.xml");
- SimpleDateFormat format = (SimpleDateFormat) context
- .getBean("defaultDateFormat");
- System.out.println(format.format(new Date()));
- }
- }
一切正常,输出如下:
更实用的例子
第一个例子主要是为了举例,在实际中用处不大,我们接着来看一个更复杂的自定义标签。我们自定义一个<fileList>标签,当Spring扫描到这个标签的时候,创建一个指定目录下的File类的集合。另外,可以使用<fileFilter>对该目录的文件进行过滤。如下:
- <core-commons:fileList id="xmlList" directory="src/extensiblexml/example">
- <core-commons:fileFilter>
- <bean class="org.apache.commons.io.filefilter.RegexFileFilter">
- <constructor-arg value=".*.java" />
- </bean>
- </core-commons:fileFilter>
- </core-commons:fileList>
上面的bean定义中,我们从“src/extensible/example”目录中筛选出java源码文件。
使用下面的测试迭代输出文件名:
- @SuppressWarnings("unchecked")
- List<File> fileList = (List<File>) context.getBean("xmlList");
- for (File file : fileList) {
- System.out.println(file.getName());
- }
输出结果如下:
根据第一个例子中的步骤,各部分配置及代码如下:
core-commons-1.0.xsd:
- <?xml version="1.0" encoding="UTF-8"?>
- <xsd:schema xmlns="http://www.example.com/schema/core-commons-1.0"
- targetNamespace="http://www.example.com/schema/core-commons-1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:beans="http://www.springframework.org/schema/beans"
- elementFormDefault="qualified"
- attributeFormDefault="unqualified"
- version="1.0">
- <xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"/>
- <xsd:element name="fileList">
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="beans:identifiedType">
- <xsd:sequence>
- <xsd:element ref="fileFilter" minOccurs="0" maxOccurs="1"/>
- <xsd:element ref="fileList" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="directory" type="xsd:string"/>
- <xsd:attribute name="scope" type="xsd:string"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="fileFilter">
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="beans:identifiedType">
- <xsd:group ref="limitedType"/>
- <xsd:attribute name="scope" type="xsd:string"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
- <xsd:group name="limitedType">
- <xsd:sequence>
- <xsd:choice minOccurs="1" maxOccurs="unbounded">
- <xsd:element ref="beans:bean"/>
- <xsd:element ref="beans:ref"/>
- <xsd:element ref="beans:idref"/>
- <xsd:element ref="beans:value"/>
- <xsd:any minOccurs="0"/>
- </xsd:choice>
- </xsd:sequence>
- </xsd:group>
- </xsd:schema>
CoreNamespaceHandler.java:
- package extensiblexml.example;
- import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
- public class CoreNamespaceHandler
- extends NamespaceHandlerSupport
- {
- @Override
- public void init() {
- this.registerBeanDefinitionParser("fileList", new FileListDefinitionParser());
- this.registerBeanDefinitionParser("fileFilter", new FileFilterDefinitionParser());
- }
- }
FileListDefinitionParser.java:
- public class FileListDefinitionParser
- extends AbstractSingleBeanDefinitionParser
- {
- /**
- * The bean that is created for this tag element
- *
- * @param element The tag element
- * @return A FileListFactoryBean
- */
- @Override
- protected Class<?> getBeanClass(Element element) {
- return FileListFactoryBean.class;
- }
- /**
- * Called when the fileList tag is to be parsed
- *
- * @param element The tag element
- * @param ctx The context in which the parsing is occuring
- * @param builder The bean definitions build to use
- */
- @Override
- protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder builder) {
- // Set the directory property
- builder.addPropertyValue("directory", element.getAttribute("directory"));
- // Set the scope
- builder.setScope(element.getAttribute("scope"));
- // We want any parsing to occur as a child of this tag so we need to make
- // a new one that has this as it's owner/parent
- ParserContext nestedCtx = new ParserContext(ctx.getReaderContext(), ctx.getDelegate(), builder.getBeanDefinition());
- // Support for filters
- Element exclusionElem = DomUtils.getChildElementByTagName(element, "fileFilter");
- if (exclusionElem != null) {
- // Just make a new Parser for each one and let the parser do the work
- FileFilterDefinitionParser ff = new FileFilterDefinitionParser();
- builder.addPropertyValue("filters", ff.parse(exclusionElem, nestedCtx));
- }
- // Support for nested fileList
- List<Element> fileLists = DomUtils.getChildElementsByTagName(element, "fileList");
- // Any objects that created will be placed in a ManagedList
- // so Spring does the bulk of the resolution work for us
- ManagedList<Object> nestedFiles = new ManagedList<Object>();
- if (fileLists.size() > 0) {
- // Just make a new Parser for each one and let them do the work
- FileListDefinitionParser fldp = new FileListDefinitionParser();
- for (Element fileListElem : fileLists) {
- nestedFiles.add(fldp.parse(fileListElem, nestedCtx));
- }
- }
- // Support for other tags that return File (value will be converted to file)
- try {
- // Go through any other tags we may find. This does not mean we support
- // any tag, we support only what parseLimitedList will process
- NodeList nl = element.getChildNodes();
- for (int i=0; i<nl.getLength(); i++) {
- // Parse each child tag we find in the correct scope but we
- // won't support custom tags at this point as it coudl destablize things
- DefinitionParserUtil.parseLimitedList(nestedFiles, nl.item(i), ctx,
- builder.getBeanDefinition(), element.getAttribute("scope"), false);
- }
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- // Set the nestedFiles in the properties so it is set on the FactoryBean
- builder.addPropertyValue("nestedFiles", nestedFiles);
- }
- public static class FileListFactoryBean
- implements FactoryBean<Collection<File>>
- {
- String directory;
- private Collection<FileFilter> filters;
- private Collection<File> nestedFiles;
- @Override
- public Collection<File> getObject() throws Exception {
- // These can be an array list because the directory will have unique's and the nested is already only unique's
- Collection<File> files = new ArrayList<File>();
- Collection<File> results = new ArrayList<File>(0);
- if (directory != null) {
- // get all the files in the directory
- File dir = new File(directory);
- File[] dirFiles = dir.listFiles();
- if (dirFiles != null) {
- files = Arrays.asList(dirFiles);
- }
- }
- // If there are any files that were created from the nested tags,
- // add those to the list of files
- if (nestedFiles != null) {
- files.addAll(nestedFiles);
- }
- // If there are filters we need to go through each filter
- // and see if the files in the list pass the filters.
- // If the files does not pass any one of the filters then it
- // will not be included in the list
- if (filters != null) {
- boolean add;
- for (File f : files) {
- add = true;
- for (FileFilter ff : filters) {
- if (!ff.accept(f)) {
- add = false;
- break;
- }
- }
- if (add) results.add(f);
- }
- return results;
- }
- return files;
- }
- @Override
- public Class<?> getObjectType() {
- return Collection.class;
- }
- @Override
- public boolean isSingleton() {
- return false;
- }
- public void setDirectory(String dir) {
- this.directory = dir;
- }
- public void setFilters(Collection<FileFilter> filters) {
- this.filters = filters;
- }
- /**
- * What we actually get from the processing of the nested tags
- * is a collection of files within a collection so we flatten it and
- * only keep the uniques
- */
- public void setNestedFiles(Collection<Collection<File>> nestedFiles) {
- this.nestedFiles = new HashSet<File>(); // keep the list unique
- for (Collection<File> nested : nestedFiles) {
- this.nestedFiles.addAll(nested);
- }
- }
- }
- }
FileFilterDefinitionParser.java
- public class FileFilterDefinitionParser
- extends AbstractSingleBeanDefinitionParser
- {
- /**
- * The bean that is created for this tag element
- *
- * @param element The tag element
- * @return A FileFilterFactoryBean
- */
- @Override
- protected Class<?> getBeanClass(Element element) {
- return FileFilterFactoryBean.class;
- }
- /**
- * Called when the fileFilter tag is to be parsed
- *
- * @param element The tag element
- * @param ctx The context in which the parsing is occuring
- * @param builder The bean definitions build to use
- */
- @Override
- protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder builder) {
- // Set the scope
- builder.setScope(element.getAttribute("scope"));
- try {
- // All of the filters will eventually end up in this list
- // We use a 'ManagedList' and not a regular list because anything
- // placed in a ManagedList object will support all of Springs
- // functionalities and scopes for us, we dont' have to code anything
- // in terms of reference lookups, EL, etc
- ManagedList<Object> filters = new ManagedList<Object>();
- // For each child node of the fileFilter tag, parse it and place it
- // in the filtes list
- NodeList nl = element.getChildNodes();
- for (int i=0; i<nl.getLength(); i++) {
- DefinitionParserUtil.parseLimitedList(filters, nl.item(i), ctx, builder.getBeanDefinition(), element.getAttribute("scope"));
- }
- // Add the filtes to the list of properties (this is applied
- // to the factory beans setFilters below)
- builder.addPropertyValue("filters", filters);
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- public static class FileFilterFactoryBean
- implements FactoryBean<Collection<FileFilter>>
- {
- private final List<FileFilter> filters = new ArrayList<FileFilter>();
- @Override
- public Collection<FileFilter> getObject() throws Exception {
- return filters;
- }
- @Override
- public Class<?> getObjectType() {
- return Collection.class;
- }
- @Override
- public boolean isSingleton() {
- return false;
- }
- /**
- * Go through the list of filters and convert the String ones
- * (the ones that were set with <value> and make them NameFileFilters
- */
- public void setFilters(Collection<Object> filterList) {
- for (Object o : filterList) {
- if (o instanceof String) {
- filters.add(new NameFileFilter(o.toString()));
- }
- else if (o instanceof FileFilter) {
- filters.add((FileFilter)o);
- }
- }
- }
- }
- }
DefinitionParserUtil.java:
- package extensiblexml.example;
- import org.springframework.beans.factory.config.BeanDefinition;
- import org.springframework.beans.factory.config.BeanDefinitionHolder;
- import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
- import org.springframework.beans.factory.support.DefaultListableBeanFactory;
- import org.springframework.beans.factory.support.ManagedList;
- import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
- import org.springframework.beans.factory.xml.ParserContext;
- import org.springframework.expression.Expression;
- import org.springframework.expression.ExpressionParser;
- import org.springframework.expression.spel.standard.SpelExpressionParser;
- import org.w3c.dom.Element;
- import org.w3c.dom.Node;
- public class DefinitionParserUtil {
- /**
- * Parses the children of the passed in ParentNode for the following tags:
- * <br/>
- * value
- * ref
- * idref
- * bean
- * property
- * *custom*
- * <p/>
- *
- * The value tag works with Spring EL even in a Spring Batch scope="step"
- *
- * @param objects The list of resultings objects from the parsing (passed in for recursion purposes)
- * @param parentNode The node who's children should be parsed
- * @param ctx The ParserContext to use
- * @param parentBean The BeanDefinition of the bean who is the parent of the parsed bean
- * (i.e. the Bean that is the parentNode)
- * @param scope The scope to execute in. Checked if 'step' to provide Spring EL
- * support in a Spring Batch env
- * @throws Exception
- */
- public static void parseLimitedList(ManagedList<Object> objects, Node node,
- ParserContext ctx, BeanDefinition parentBean, String scope)
- throws Exception
- {
- parseLimitedList(objects, node, ctx, parentBean, scope, true);
- }
- /**
- * Parses the children of the passed in ParentNode for the following tags:
- * <br/>
- * value
- * ref
- * idref
- * bean
- * property
- * *custom*
- * <p/>
- *
- * The value tag works with Spring EL even in a Spring Batch scope="step"
- *
- * @param objects The list of resultings objects from the parsing (passed in for recursion purposes)
- * @param parentNode The node who's children should be parsed
- * @param ctx The ParserContext to use
- * @param parentBean The BeanDefinition of the bean who is the parent of the parsed bean
- * (i.e. the Bean that is the parentNode)
- * @param scope The scope to execute in. Checked if 'step' to provide Spring EL
- * support in a Spring Batch env
- * @param supportCustomTags Should we support custom tags within our tags?
- * @throws Exception
- */
- @SuppressWarnings("deprecation")
- public static void parseLimitedList(ManagedList<Object> objects, Node node,
- ParserContext ctx, BeanDefinition parentBean, String scope, boolean supportCustomTags)
- throws Exception
- {
- // Only worry about element nodes
- if (node.getNodeType() == Node.ELEMENT_NODE) {
- Element elem = (Element)node;
- String tagName = node.getLocalName();
- if (tagName.equals("value")) {
- String val = node.getTextContent();
- // to get around an issue with Spring Batch not parsing Spring EL
- // we will do it for them
- if (scope.equals("step")
- && (val.startsWith("#{") && val.endsWith("}"))
- && (!val.startsWith("#{jobParameters"))
- )
- {
- // Set up a new EL parser
- ExpressionParser parser = new SpelExpressionParser();
- // Parse the value
- Expression exp = parser.parseExpression(val.substring(2, val.length()-1));
- // Place the results in the list of created objects
- objects.add(exp.getValue());
- }
- else {
- // Otherwise, just treat it as a normal value tag
- objects.add(val);
- }
- }
- // Either of these is a just a lookup of an existing bean
- else if (tagName.equals("ref") || tagName.equals("idref")) {
- objects.add(ctx.getRegistry().getBeanDefinition(node.getTextContent()));
- }
- // We need to create the bean
- else if (tagName.equals("bean")) {
- // There is no quick little util I could find to create a bean
- // on the fly programmatically in Spring and still support all
- // Spring functionality so basically I mimic what Spring actually
- // does but on a smaller scale. Everything Spring allows is
- // still supported
- // Create a factory to make the bean
- DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
- // Set up a parser for the bean
- BeanDefinitionParserDelegate pd = new BeanDefinitionParserDelegate(ctx.getReaderContext());
- // Parse the bean get its information, now in a DefintionHolder
- BeanDefinitionHolder bh = pd.parseBeanDefinitionElement(elem, parentBean);
- // Register the bean will all the other beans Spring is aware of
- BeanDefinitionReaderUtils.registerBeanDefinition(bh, beanFactory);
- // Get the bean from the factory. This will allows Spring
- // to do all its work (EL processing, scope, etc) and give us
- // the actual bean itself
- Object bean = beanFactory.getBean(bh.getBeanName());
- objects.add(bean);
- }
- /*
- * This is handled a bit differently in that it actually sets the property
- * on the parent bean for us based on the property
- */
- else if (tagName.equals("property")) {
- BeanDefinitionParserDelegate pd = new BeanDefinitionParserDelegate(ctx.getReaderContext());
- // This method actually set eh property on the parentBean for us so
- // we don't have to add anything to the objects object
- pd.parsePropertyElement(elem, parentBean);
- }
- else if (supportCustomTags) {
- // handle custom tag
- BeanDefinitionParserDelegate pd = new BeanDefinitionParserDelegate(ctx.getReaderContext());
- BeanDefinition bd = pd.parseCustomElement(elem, parentBean);
- objects.add(bd);
- }
- }
- }
- }
spring.schemas
- http\://www.mycompany.com/schema/myns/myns.xsd=extensiblexml/customtag/myns.xsd
- http\://www.example.com/schema/core-commons-1.0.xsd=extensiblexml/example/core-commons-1.0.xsd
spring.handlers
- http\://www.mycompany.com/schema/myns=extensiblexml.customtag.MyNamespaceHandler
- http\://www.example.com/schema/core-commons-1.0=extensiblexml.example.CoreNamespaceHandler
小结:
要自定义Spring的配置标签,需要一下几个步骤:
**使用XSD定义XML配置中标签元素的结构(myns.XSD)
**提供该XSD命名空间的处理类,它可以处理多个标签定义(MyNamespaceHandler.java)
**为每个标签元素的定义提供解析类。(SimpleDateFormatBeanDefinitionParser.java)
**两个特殊文件通知Spring使用自定义标签元素(spring.handlers 和spring.schemas)
参考资料:
Spring官方的Extensible XML Authoring文档:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/extensible-xml.html
一个不错的教程:
http://sloanseaman.com/wordpress/2012/03/26/spring-custom-tags-extensible-xml-part-1/
http://sloanseaman.com/wordpress/2012/04/08/spring-custom-tags-extensible-xml-part-2/
转载请注明出处。
+
+
+
=
+
+
+
相关推荐
通过研究这个例子,我们可以学习到如何将业务逻辑抽象出来,封装成自定义标签,使Spring配置更加简洁。这对于大型项目来说尤其重要,因为它可以提高代码的可读性和模块化程度。 此外,理解自定义标签的工作原理还能...
总之,自定义Spring XML标签是一项强大的功能,它允许开发者按照项目特性定制配置语法,提高代码的可读性和可维护性。通过实现`NamespaceHandler`和`BeanDefinitionParser`,我们可以轻松地将业务逻辑融入到Spring的...
在Spring框架中,自定义配置文件和标签是提高代码可读性和灵活性的重要手段。这个名为"Spring自定义配置文件便签[Maven]工程可运行"的项目,显然是一个基于Maven构建的Spring 5.0应用程序,它包含了自定义配置文件和...
自定义XML配置通常会涉及到Spring的`<beans>`标签和`<bean>`标签,用于声明和实例化对象。在XML中定义拦截器,我们需要创建一个实现了`HandlerInterceptor`接口的类,并在XML配置文件中声明这个类。然后,我们可以...
然后,你需要在Spring配置中注册这个自定义标签。在`WebMvcConfigurer`的实现中,添加`freemarkerConfiguration` bean,并使用`freemarkerConfigurer`的`setCustomTags`方法添加自定义标签: ```java @...
在Spring框架中,自定义标签解析是扩展Spring配置能力的重要方式。通过自定义标签,开发者可以创建更加符合业务逻辑和可读性强的XML配置文件。本文将深入剖析Spring 5.2.9版本中自定义标签的解析过程,旨在帮助读者...
在Spring框架中,自定义标签是一项非常实用的功能,它允许我们创建自己的XML标签来简化配置,提高代码可读性,并实现特定的业务逻辑。本文将深入探讨Spring自定义标签的概念、实现过程及其在实际开发中的应用。 ...
通过定义自定义Schema,我们可以限制或扩展Spring配置文件中可用的元素和属性,确保配置的正确性和一致性。 实现自定义Schema解析的过程主要包括以下几个步骤: 1. **定义Schema**: 使用XSD(XML Schema ...
当我们需要在Spring配置文件中引入自定义标签时,`NamespaceHandler`起着至关重要的作用。这篇博文通过分析`spring-web-namespacehandler`,将深入探讨这一主题。 首先,`NamespaceHandler`是Spring框架解析XML配置...
在Spring框架中,自定义标签的解析过程是一个关键的组件,它使得开发者能够通过XML配置文件以更加直观和简洁的方式声明Bean的定义。本节将深入探讨Spring 5.2.9版本中自定义标签的解析机制,以及背后的源码实现。 ...
在Spring框架中,自定义标签和注解解析是两个关键的特性,它们使得代码与配置的集成更加紧密,简化了应用程序的开发。本篇文章将深入探讨Spring如何处理这两种类型的元数据。 首先,让我们来理解Spring如何解析...
在Spring框架中,自定义标签和注解解析是核心功能之一,它们允许开发者根据特定需求扩展和定制Spring的配置方式。本文将深入探讨这两个概念的解析原理,帮助读者理解Spring如何处理自定义标签和注解。 首先,让我们...
本教程将详细介绍如何在Spring Boot中自定义日志配置,特别是通过`logback-spring.xml`文件来实现。 首先,我们需要理解`logback-spring.xml`与传统的`logback.xml`的区别。`logback-spring.xml`是专门为Spring ...
- 配置文件注册:在Spring的XML配置文件中,通过`<bean>`标签的`property-editorRegistrar`属性指定一个实现了`PropertyEditorRegistrar`接口的类。在该类的`registerEditors()`方法中,可以使用`...
本项目"自定义分页标签struts2,spring"是针对Struts2和Spring框架的一个自定义标签实现,旨在简化开发过程,提高代码的可复用性和可维护性。下面我们将详细探讨这个项目中的关键技术点。 首先,Struts2是一个非常...
在Spring框架中,自定义XML标签是扩展Spring配置能力的一种方式,这允许我们创建更加语义化的配置元素,提高代码的可读性和可维护性。本文将深入探讨如何结合Spring来实现自定义XML标签,并利用FactoryBean进行代理...
本文将详细探讨SpringSecurity中关于自定义用户权限信息存取的实现方法,包括如何通过配置文件和数据库来管理用户的认证信息和权限数据。 首先,当我们谈论用户权限信息的存取,实际上是在处理两个方面的问题:用户...
Spring框架也有自己的标签库,如Spring Taglib,可以简化JSP页面中的Spring Bean引用。而在Freemarker中,可以通过扩展其API创建自定义指令,实现更复杂的逻辑或功能。 总结一下,Struts2、Spring和Freemarker的...
在Spring配置文件中,可以通过`<aop:aspectj-autoproxy/>`标签启用AspectJ的自动代理功能。这意味着Spring容器会自动为标记了@Aspect注解的类创建AOP代理,而无需手动配置。 #### 3. **自定义注解定义切点** 为了...