Heim  >  Artikel  >  Java  >  So passen Sie Spring-Konfigurations-Tags in Java an

So passen Sie Spring-Konfigurations-Tags in Java an

WBOY
WBOYnach vorne
2023-04-24 17:16:171415Durchsuche

Einführung:

In Spring werden im Allgemeinen Elemente wie zum Konfigurieren einer Bean verwendet. Spring scannt diese Konfigurationen, erstellt Objekte basierend auf der Konfiguration und speichert sie im Container Wir werden sie aus dem Container abrufen. Nehmen Sie sie heraus oder fügen Sie sie als Eigenschaft ein, wenn Sie andere Beans konfigurieren. Eine Einschränkung bei der Verwendung der Bean-Konfiguration besteht darin, dass wir der XML-Schemadefinition der Konfigurationsdatei folgen müssen, was in den meisten Fällen kein Problem darstellt. In einigen Fällen möchten wir jedoch eine flexiblere Bean-Konfiguration erreichen. Spring bietet hierfür benutzerdefinierte Tag-Unterstützung, auch bekannt als Extensible XML Authoring. Durch diesen Erweiterungspunkt können wir das benötigte Konfigurationsformat flexibel anpassen.

Wenn wir beispielsweise eine Verantwortungskette zum Entwerfen einer Anwendung verwenden, möchten wir die Verantwortungskette möglicherweise folgendermaßen konfigurieren:

<chain id="orderChain" class="foo.bar">
    <handler> handler1</handler>
    <hadnler> handler2</handler>
</chain>

Wenn Spring einen Container erstellt und ein solches Element gescannt wird, Es wird entsprechend unserer vorherigen Konfiguration konfiguriert. Die Definition instanziiert ein Verantwortungskettenobjekt und füllt die Eigenschaften auf. Daher kann dieses spezielle -Tag als Alternative zum -Tag verwendet werden. Mit dem benutzerdefinierten Tag von Spring können wir eine solche Bean-Konfiguration vollständig implementieren. In einem Anwendungsframework auf Produktebene können komplexere benutzerdefinierte Etikettenelemente implementiert werden. Als Einstiegseinführung definieren wir eine Klasse SimpleDateFormat zum Konfigurieren der Datumsformatierung. Natürlich ist die Verwendung des traditionellen völlig ausreichend, wir verwenden es hier nur als Beispiel.

Ein HelloWorld-Beispiel:

Der erste Schritt beim Anpassen von Tags besteht darin, die XML-Struktur des Tag-Elements zu definieren. So sieht es aus, wenn XSD zum Elementieren der Struktur des Elements verwendet wird, das wir anpassen möchten.

Wir definieren ein einfaches XSD wie folgt:

<?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>

In dieser XSD-Definition gibt es ein Tag namens dateformat, das benutzerdefinierte Tag, das wir verwenden, um das Bean-Tag zu ersetzen. Beachten Sie, dass wir Springs eigenen Beans-Namespace importiert und das Dateformat-Tag basierend auf Beans:identifiedType definiert haben. Das heißt, unser Tag kann das id-Attribut wie das -Tag haben. Gleichzeitig haben wir zwei Attribute „Nachsicht“ und „Muster“ hinzugefügt. Das fühlt sich ein bisschen wie eine Vererbung an.

Nachdem wir die XSD definiert haben, müssen wir Spring mitteilen, wie ein Objekt erstellt werden soll, wenn es auf ein solches Tag (Namespace + Elementname) stößt. Im Frühjahr wird NamespaceHandler verwendet, um diese Aufgabe zu erfüllen. Daher müssen wir eine NamespaceHandler-Implementierung bereitstellen, um das benutzerdefinierte -Tag-Element zu verarbeiten.

Eine einfache Implementierung ist wie folgt:

package extensiblexml.customtag;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class MyNamespaceHandler extends NamespaceHandlerSupport {
	public void init() {
		registerBeanDefinitionParser("dateformat",
				new SimpleDateFormatBeanDefinitionParser());
	}
 
}

Wir haben einen Bean-definierten Parser in der Initialisierungsmethode registriert. Dieser Parser wird zum Parsen benutzerdefinierter Konfigurations-Tags verwendet.

Die Implementierung ist wie folgt:

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));
        }
    }
 
}

Der doParse dieses Parsers implementiert die spezifische Logik des Parsens. Mit den von Spring bereitgestellten Unterstützungsklassen können wir das Parsen problemlos abschließen. Die oben genannten drei Dateien werden im selben Verzeichnis abgelegt, dh die XSD-Datei und der Java-Code werden im selben Verzeichnis abgelegt. Nachdem die Codierung abgeschlossen ist, müssen noch einige Konfigurationsarbeiten durchgeführt werden. Wir müssen Spring mitteilen, dass wir ein benutzerdefiniertes Tag-Element verwenden und Spring mitteilen, wie das Element analysiert werden soll, andernfalls ist Spring nicht so intelligent. Hier sind zwei Konfigurationsdateien erforderlich. Auf derselben Ebene wie der Code-Root-Pfad verfügt die Matratze über eine Datei namens META-INF. Und erstellen Sie darin Klassen mit den Namen spring.handlers und spring.schemas, die verwendet werden, um Spring die Dokumentstruktur des benutzerdefinierten Tags und die Klasse, die es analysiert, mitzuteilen. Der Inhalt der beiden Dateien lautet wie folgt:

spring.handlers:

http://www.mycompany.com/schema/myns=extensiblexml.customtag.MyNamespaceHandler

Die linke Seite des Gleichheitszeichens ist der targetNamespace im XSD-Definitionsattribut, die rechte Seite ist der vollständig qualifizierte Name von NamespaceHandler.

spring.schemas:

http://www.mycompany.com/schema/myns/myns.xsd=extensiblexml/customtag/myns.xsd

Dann konfigurieren Sie die Bean wie gewohnt, ganz einfach test definieren wir eine 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>

In Eclipse ist die gesamte Projektstruktur wie folgt:

So passen Sie Spring-Konfigurations-Tags in Java an

Abschließend schreiben wir eine Testklasse, um zu testen, ob es funktionieren kann:

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()));
 
	}
 
}

Everything ist normal, Ausgabe wie folgt:

So passen Sie Spring-Konfigurations-Tags in Java an

Weitere praktische Beispiele

Das erste Beispiel dient hauptsächlich der Veranschaulichung und ist in der Praxis nicht sehr nützlich. Fahren wir mit einem komplexeren benutzerdefinierten Tag fort. Wir passen ein -Tag an. Wenn Spring dieses Tag scannt, erstellt es eine Sammlung von Dateiklassen im angegebenen Verzeichnis. Darüber hinaus können Sie mit Dateien in diesem Verzeichnis filtern.

Wie folgt:

<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>

In der obigen Bean-Definition filtern wir die Java-Quellcodedateien aus dem Verzeichnis „src/extensible/example“.

Verwenden Sie den folgenden Ausgabedateinamen für die Testiteration:

@SuppressWarnings("unchecked")
List<File> fileList = (List<File>) context.getBean("xmlList");
for (File file : fileList) {
	System.out.println(file.getName());
}

输出结果如下:

So passen Sie Spring-Konfigurations-Tags in Java an

根据第一个例子中的步骤,各部分配置及代码如下:

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&#39;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&#39;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&#39;s and the nested is already only unique&#39;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 &#39;ManagedList&#39; and not a regular list because anything
			// placed in a ManagedList object will support all of Springs
			// functionalities and scopes for us, we dont&#39; 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&#39;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 &#39;step&#39; 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&#39;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 &#39;step&#39; 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&#39;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)

Das obige ist der detaillierte Inhalt vonSo passen Sie Spring-Konfigurations-Tags in Java an. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen