Spring source Read loading XML configuration file

Source: Internet
Author: User
Tags aop relative valid

Start with a simple example:

Scene class Client.java

Package Com.dusk.bean;

Import Org.junit.Test;
Import org.springframework.beans.factory.BeanFactory;
Import org.springframework.beans.factory.xml.XmlBeanFactory;
Import Org.springframework.core.io.ClassPathResource;
Import Org.springframework.core.io.Resource;

public class Client {
	@Test public
	void Test () {
		Resource resource=new classpathresource ("com/dusk/bean/ Bean.xml ");
		Beanfactory beanfactory=new xmlbeanfactory (Resource);
		Hello Hello=beanfactory.getbean (hello.class);
		Hello.sayhello ();
	}
	
}

Bean entity class Hello.java

Package Com.dusk.bean;

public class Hello {
	private String name;
	
	public void SetName (String name) {
		this.name = name;
	}

	public void SayHello () {
		System.out.println ("Hello," +name+ "!");
	}
}

Configuration file Bean.xml

<?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:aop= "http://www.springframework.org/ SCHEMA/AOP "
	xsi:schemalocation=" Http://www.springframework.org/schema/aop http://www.springframework.org/ Schema/aop/spring-aop.xsd
		Http://www.springframework.org/schema/beans Http://www.springframework.org/schema /beans/spring-beans.xsd ">
	<bean id=" Hello "class=" Com.dusk.bean.Hello ">
		<property name=" name " value= "Dusk"/>
	</bean>
</beans>
Of course, the output is:

Hello, dusk!.

Next, let's look at the loading process for XML configuration.

1. Classpathresource is used to point to a resource under a classpath, where com/dusk/bean/bean.xml represents an XML file that contains the spring bean configuration.

public class Xmlbeanfactory extends Defaultlistablebeanfactory {private final


	Xmlbeandefinitionreader reader = new Xmlbeandefinitionreader (this);
	 /** * Create A new xmlbeanfactory with the given resource, * which must is parsable using DOM. * @param resource XML resource to load beans definitions from * @throws beansexception in case of loading or parsing Erro
	RS */Public xmlbeanfactory (Resource Resource) throws Beansexception {This (Resource, null);
	 }/** * Create a new xmlbeanfactory with the given input stream, * which must is parsable using DOM. * @param resource XML resource to load beans definitions from * @param parentbeanfactory parent Bean Factory * @throws Beansexception in case of loading or parsing errors */public xmlbeanfactory (Resource Resource, Beanfactory parentbeanf
		Actory) throws Beansexception {super (parentbeanfactory); <strong>this.reader.loadbeandefinitions (Resource);</strong>}} 

The bold code above allows you to know that the configuration file is loaded by Xmlbeandefinitionreader. First, the XML configuration file for spring is handled by sax. Refer to the blog for sax

Sax detailed.


Draw a simple sequence diagram, the use of sequence diagram is welcome to correct.

We can see from the diagram that parsing XML is done primarily by the Org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader class, which is the default parsing class provided by spring, and of course you can customize Their own resolution.

It can be seen that spring provides a good enhancement mechanism for you to enhance this class, with two empty methods reserved for developers.

	/**
	 * Parse custom element where
	 * <p>allow the XML to is extensible by processing any custom element types first,
	 * BEF Ore we start to process the bean definitions. This method was a natural * extension point for any and other
	 custom pre-processing of the XML.
	 * <p>the default implementation is empty. Subclasses can override this method
	 to * Convert custom elements into standard Spring beans definitions, for example.
  * Implementors has access to the parser ' s bean definition Reader
	 and the * underlying XML resource, through the CO Rresponding accessors.
	 * @see #getReaderContext ()
	 */
	protected void Preprocessxml (Element root) {
	}
And

	/**
	 * Allow the XML to being extensible by processing a custom element types last,
	 * after we finished processing T He bean definitions. This method was a natural * extension point for any and other
	 custom post-processing of the XML.
	 * <p>the default implementation is empty. Subclasses can override this method
	 to * Convert custom elements into standard Spring beans definitions, for example.
  * Implementors has access to the parser ' s bean definition Reader
	 and the * underlying XML resource, through the CO Rresponding accessors.
	 * @see #getReaderContext ()
	 */
	protected void Postprocessxml (Element root) {
	}

Both of these methods are protected, in order to facilitate the subclass rewrite, and both are empty methods.

The main parsing XML method is Parsebeandefinitions, as follows:

        /**
	 * Parse The elements at the root level in the document:
	 * "Import", "Alias", "Bean".
	 * @param root the DOM root element
	 of the document *
	/protected void parsebeandefinitions (element root, Beandefini Tionparserdelegate delegate) {
		if (delegate.isdefaultnamespace (root)) {
			NodeList nl = root.getchildnodes ();
			for (int i = 0; i < nl.getlength (); i++) {
				node node = nl.item (i);
				if (node instanceof element) {
					element ele = (element) node;
					if (Delegate.isdefaultnamespace (ele)) {
						parsedefaultelement (ele, delegate);
					}
					else {
						delegate.parsecustomelement (ele);
		}}}} else {
			delegate.parsecustomelement (root);
		}
	}

It can be seen that it is loop-processed, and then read the detailed content:
        
	 /* Parsing process, analysis of the default elements for example, Bean
	 *
	/private void Parsedefaultelement (element ele, Beandefinitionparserdelegate delegate) {
		if (delegate.nodenameequals (Ele, import_element)) {
			//import element
			Importbeandefinitionresource (ele);
		}
		else if (delegate.nodenameequals (Ele, alias_element)) {
			//alias element
			processaliasregistration (ele);
		}
		else if (delegate.nodenameequals (Ele, bean_element)) {
			//bean element
			processbeandefinition (Ele, delegate);
		}
		Else if (delegate.nodenameequals (Ele, nested_beans_element)) {
			//beans element
			//Recurse (Recursive)
			Doregisterbeandefinitions (ele);
		}
	}

And

       /** * Parse an ' import ' element and load the bean definitions * from the given resource into the Bean factory. 
		*/protected void Importbeandefinitionresource (Element ele) {String location = Ele.getattribute (Resource_attribute); if (!
			Stringutils.hastext (location)) {Getreadercontext (). Error ("Resource location must not being empty", ele);
		Return }//Resolve system properties:e.g. "${user.dir}" location = Getreadercontext (). Getenvironment (). Resolverequiredplac

		Eholders (location);

		set<resource> actualresources = new linkedhashset<resource> (4);
		Discover whether the location was an absolute or relative URI Boolean absolutelocation = false; try {absolutelocation = Resourcepatternutils.isurl (location) | |
		Resourceutils.touri (location). Isabsolute (); } catch (URISyntaxException ex) {//cannot convert to a URI, considering the location relative//unless it is t He well-known Spring prefix "classpath*:"}//Absolute or relAtive? if (absolutelocation) {try {int importcount = Getreadercontext (). Getreader (). loadbeandefinitions (Location, actual
				Resources); if (logger.isdebugenabled ()) {Logger.debug ("imported" + importcount + "Bean definitions from URL location [" + Loc
				ation + "]");  }} catch (Beandefinitionstoreexception ex) {Getreadercontext (). Error ("Failed to import bean definitions
			From URL location ["+ Location +"] ", Ele, ex);
			}} else {//No URL--considering resource location as relative to the current file.
				try {int importcount;
				Resource Relativeresource = Getreadercontext (). GetResource (). createrelative (location); if (relativeresource.exists ()) {Importcount = Getreadercontext (). Getreader (). Loadbeandefinitions (RelativeResource)
					;
				Actualresources.add (Relativeresource);
					} else {String baselocation = Getreadercontext (). GetResource (). GetURL (). toString (); Importcount = Getreadercontext (). Getreader (). LoAdbeandefinitions (Stringutils.applyrelativepath (baselocation, location), actualresources); } if (logger.isdebugenabled ()) {Logger.debug ("imported" + importcount + "Bean definitions from relative Locati
				On ["+ Location +"] ");
			}} catch (IOException ex) {Getreadercontext (). Error ("Failed to resolve current resource location", Ele, ex); } catch (Beandefinitionstoreexception ex) {Getreadercontext (). Error ("Failed to import beans definitions from RelA
			tive location ["+ Location +"] ", Ele, ex);
		}} resource[] Actresarray = Actualresources.toarray (New resource[actualresources.size ());
	Getreadercontext (). fireimportprocessed (location, Actresarray, Extractsource (ele));
	 }/** * Process the given alias element, registering the alias with the registry.
		*/protected void processaliasregistration (Element ele) {String name = Ele.getattribute (Name_attribute);
		String alias = Ele.getattribute (Alias_attribute); Boolean valid = True if (!
			Stringutils.hastext (name)) {Getreadercontext (). Error ("Name must not is empty", ele);
		valid = false; } if (!
			Stringutils.hastext (alias)) {Getreadercontext (). Error ("Alias must Not is empty", ele);
		valid = false;
			} if (valid) {try {getreadercontext (). GetRegistry (). Registeralias (name, alias); } catch (Exception ex) {Getreadercontext (). Error ("Failed to register alias '" + Alias + "' for Beans with Nam
			E ' "+ Name +" ' ", Ele, ex);
		} getreadercontext (). firealiasregistered (name, alias, Extractsource (Ele));
 }
	}

	/**
	 * Process The given bean element, parsing the bean definition
	 * and registering it with the registry.
	 *
	/protected void processbeandefinition (Element ele, beandefinitionparserdelegate delegate) {
		Beandefinitionholder Bdholder = delegate.parsebeandefinitionelement (ele);
		if (Bdholder! = null) {
			Bdholder = delegate.decoratebeandefinitionifrequired (Ele, bdholder);
			try {
				//registers the bean definition//register as Beanfactory in the
				final decorated instance.
				Beandefinitionreaderutils.registerbeandefinition (Bdholder, Getreadercontext (). GetRegistry ());
			}
			catch (Beandefinitionstoreexception ex) {
				getreadercontext (). Error ("Failed to register bean definition with Name '" +
						Bdholder.getbeanname () + "'", Ele, ex);
			}
			<strong>//sends an event to the IOC container, representing parsing and registration completion
			//Send registration event.
			Getreadercontext (). firecomponentregistered (New Beancomponentdefinition (Bdholder));</strong>
		}
	}
The above is the spring default parsing XML step.

He who wants to be a man will suffer before his ancestors.







Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.