Rumah >Java >javaTutorial >Bagaimana untuk menyesuaikan teg konfigurasi Spring dalam Java

Bagaimana untuk menyesuaikan teg konfigurasi Spring dalam Java

WBOY
WBOYke hadapan
2023-04-24 17:16:171470semak imbas

Pengenalan:

Dalam Spring, elemen seperti biasanya digunakan untuk mengkonfigurasi kacang Spring akan mengimbas konfigurasi ini semasa membuat bekas dan mencipta objek berdasarkan konfigurasi . Simpannya di dalam bekas, dan kemudian keluarkan dari bekas, atau suntikkannya sebagai sifat apabila mengkonfigurasi kacang lain. Satu had penggunaan konfigurasi kacang ialah kita perlu mengikut takrifan Skema XML bagi fail konfigurasi, yang tidak menimbulkan masalah dalam kebanyakan kes. Tetapi dalam beberapa kes, kami ingin mencapai konfigurasi kacang yang lebih fleksibel. Spring menyediakan Sokongan tag tersuai untuk ini, juga dikenali sebagai Pengarangan XML Boleh Diperluas. Melalui titik pengembangan ini, kami boleh menyesuaikan format konfigurasi yang kami perlukan secara fleksibel.

Sebagai contoh, jika kami menggunakan rantaian tanggungjawab untuk mereka bentuk aplikasi, maka kami mungkin mahu mengkonfigurasi rantaian tanggungjawab dengan cara berikut:

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

Bekas penciptaan Spring Fail Apabila elemen sedemikian diimbas, objek rantaian tanggungjawab akan digunakan mengikut definisi terdahulu kami dan atribut akan diisi. Oleh itu, tag khas ini boleh digunakan sebagai alternatif kepada tag Dengan Tag Tersuai Spring, kami boleh melaksanakan sepenuhnya konfigurasi kacang tersebut. Dalam rangka kerja aplikasi peringkat produk, elemen label tersuai yang lebih kompleks boleh dilaksanakan. Sebagai pengenalan peringkat kemasukan, kami mentakrifkan kelas SimpleDateFormat untuk mengkonfigurasi pemformatan tarikh. Sudah tentu, menggunakan tradisional sudah memadai, kami di sini hanya sebagai contoh.

Contoh HelloWorld:

Langkah pertama dalam menyesuaikan teg adalah untuk mentakrifkan struktur XML elemen teg, iaitu, menggunakan XSD untuk elemen struktur teg. elemen yang kami mahu sesuaikan.

Kami mentakrifkan XSD mudah seperti berikut:

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

Dalam takrifan XSD ini, terdapat teg yang dipanggil dateformat, iaitu apa yang kami gunakan untuk menggantikan kacang tag Label tersuai. Perhatikan bahawa kami mengimport ruang nama kacang Spring sendiri dan menentukan teg format tarikh berdasarkan beans:identifiedType. Maksudnya, teg kami boleh mempunyai atribut id seperti teg Pada masa yang sama, kami menambah dua sifat lembut dan corak. Ini terasa seperti warisan.

Selepas mentakrifkan XSD, kita perlu memberitahu Spring cara mencipta objek apabila ia menemui teg sedemikian (ruang nama + nama elemen). Pada Musim Bunga, NamespaceHandler digunakan untuk menyelesaikan tugas ini. Oleh itu, kami perlu menyediakan pelaksanaan NamespaceHandler untuk mengendalikan elemen teg

Pelaksanaan mudah adalah seperti berikut:

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

Kami telah mendaftarkan penghurai definisi Bean dalam kaedah pemulaan ini digunakan untuk menghuraikan teg Konfigurasi tersuai.

Pelaksanaan adalah seperti berikut:

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

Dalam doParse penghurai ini, logik penghuraian khusus dilaksanakan Dengan kelas sokongan yang disediakan oleh Spring, kami boleh menyelesaikan analisis dengan mudah. Tiga fail di atas diletakkan dalam direktori yang sama, iaitu fail XSD dan kod Java diletakkan dalam direktori yang sama. Selepas pengekodan selesai, beberapa kerja konfigurasi masih perlu dilakukan. Kita mesti memberitahu Spring bahawa kita akan menggunakan elemen tag tersuai dan memberitahu Spring cara menghuraikan elemen, jika tidak Spring tidak begitu pintar. Dua fail konfigurasi diperlukan di sini Pada tahap yang sama dengan laluan akar kod, tilam ialah fail yang dipanggil META-INF. Dan buat kelas bernama spring.handlers dan spring.schemas di dalam, yang digunakan untuk memberitahu Spring struktur dokumen teg tersuai dan kelas yang menghuraikannya. Kandungan kedua-dua fail tersebut adalah seperti berikut:

spring.handlers:

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

Sebelah kiri tanda sama ialah atribut targetNamespace dalam takrifan XSD, dan sebelah kanan ialah nama NamespaceHandler yang layak sepenuhnya.

spring.schemas:

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

Kemudian konfigurasikan kacang seperti biasa, sebagai ujian mudah, kami mentakrifkan kacang:

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

Dalam Eclipse, keseluruhan projek Strukturnya adalah seperti berikut:

Bagaimana untuk menyesuaikan teg konfigurasi Spring dalam Java

Akhirnya kami menulis kelas ujian untuk menguji sama ada ia berfungsi:

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

Semuanya baik-baik saja, outputnya adalah seperti berikut:

Bagaimana untuk menyesuaikan teg konfigurasi Spring dalam Java

Contoh yang lebih praktikal

Contoh pertama adalah terutamanya untuk ilustrasi, tidak banyak digunakan dalam amalan. Mari kita lihat teg tersuai yang lebih kompleks. Kami menyesuaikan teg Apabila Spring mengimbas teg ini, ia mencipta koleksi kelas Fail dalam direktori yang ditentukan. Selain itu, anda boleh menggunakan untuk menapis fail dalam direktori ini.

adalah seperti berikut:

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

Dalam definisi kacang di atas, kami menapis fail kod sumber java daripada direktori "src/extensible/example".

Gunakan nama fail output lelaran ujian berikut:

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

输出结果如下:

Bagaimana untuk menyesuaikan teg konfigurasi Spring dalam Java

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

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)

Atas ialah kandungan terperinci Bagaimana untuk menyesuaikan teg konfigurasi Spring dalam Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam