Hibernate suggests that, in an application system, the configuration and sessionfactory are single cases, and the session is a number of examples.
Hibernate starts loading the default configuration file when we execute the following code
New Configuration (). Configure ()
Hibernate will look for a configuration file named "Hibernate.cfg.xml" under the root path of Classath, and parse it, as shown in procedure 1
Figure 1: Timing diagram of the configuration file loading process
The following analysis of the configuration file loading process
Step 1.configuration.configure ()
The method is defined in the Org/hibernate/cfg/configuration.java file
Public Configuration Configure () throws Hibernateexception {Configure ("/hibernate.cfg.xml");
Call the overloaded method configure ("/hibernate.cfg.xml"), passing in the default profile name as an argument
Step 2.configuration.doconfigure
The method is defined in the Org/hibernate/cfg/configuration.java file
Protected Configuration doconfigure (Document doc) throws Hibernateexception {Element Sfnode = Doc.getrootelement (). Element ("Session-factory"); String name = Sfnode.attributevalue ("name"), if (name! = null) {Properties.setproperty (Environment.session_factory_nam E, name);} Addproperties (Sfnode);p arsesessionfactory (Sfnode, name); Element secNode = Doc.getrootelement (). Element ("security"); if (secNode! = null) {parsesecurity (secNode);} Log.info ("Configured sessionfactory:" + name); Log.debug ("Properties:" + properties); return this;
This method will load the configuration process, transfer to two indirect layer methods to handle, Addproperties () and Parsesessionfactory
Step 3.configuration.addproperties
The method is defined in the Org/hibernate/cfg/configuration.java file
private void Addproperties (Element parent) {Iterator ITR = Parent.elementiterator ("property"), while (Itr.hasnext ()) {E Lement node = (Element) itr.next (); String name = Node.attributevalue ("name"); String value = Node.gettext (). Trim (); Log.debug (name + "=" + value);p roperties.setproperty (name, value); if (!name.star Tswith ("Hibernate")) {Properties.setproperty ("hibernate." + name, value);}} Environment.verifyproperties (properties);}
This method mainly analyzes the content of the property element in the configuration file, and stores it in the properties member variable, and the properties is a properties instance.
If the value of name does not begin with "hibernate", it is found in the If judgment condition and will be automatically complete
Step 4. Configuration.parsesessionfactory
The method is defined in the Org/hibernate/cfg/configuration.java file
private void Parsesessionfactory (Element sfnode, String name) {Iterator elements = Sfnode.elementiterator (); while (Eleme Nts.hasnext ()) {element subelement = (Element) Elements.next (); String subelementname = Subelement.getname (), if ("Mapping". Equals (Subelementname)) {parsemappingelement (subelement, name);} else if ("Class-cache". Equals (Subelementname)) {...} else if ("Collection-cache". Equals (Subelementname)) {...} else if ("Listener". Equals (Subelementname)) {Parselistener (subelement);} else if ("event". Equals (Subelementname)) {parseevent (subelement);}}}
Formal parameter Sfnode point to session-factory element node
Parameter name is the Name property value of session-factory, equal to NULL
Since we have added the following configuration in the configuration file:
<mapping resource= "Com/demo/model/student.hbm.xml"/><mapping resource= "com/demo/model/ Certificate.hbm.xml "/><mapping resource=" Com/demo/model/user.hbm.xml "/><mapping resource=" com/demo/ Model/role.hbm.xml "/>
At this point the condition is satisfied with "" "Mapping". Equals (subelementname) "Branch
Step 5.configuration.parsemappingelement
The method is defined in the Org/hibernate/cfg/configuration.java file
private void Parsemappingelement (Element mappingelement, String name) {Final Attribute ResourceAttribute = Mappingelement.attribute ("resource"); if (resourceattribute! = null) {final String resourcename = Resourceattribu Te.getvalue (); Log.debug ("Session-factory config [{}] named resource [{}] for mapping", name, resourcename); AddResource ( resourcename);} else if (fileattribute! = null) {...} else if (jarattribute! = null) {...} else if (packageattribute! = null) {...} else if (classattribute! = null) {...} else {throw new mappingexception ("<mapping> element in configuration specifies no known attributes");}}
We configure <mapping resource= "Com/demo/model/user.hbm.xml"/> in Hibernate.cfg.xml,
satisfies the condition ResourceAttribute! = NULL, calls the AddResource (resourcename) method
Step 6.configuration.addresource
The method is defined in the Org/hibernate/cfg/configuration.java file
Public Configuration AddResource (String resourcename) throws Mappingexception {Log.info ("Reading mappings from Resource : "+ resourcename); ClassLoader Contextclassloader = Thread.CurrentThread (). Getcontextclassloader (); InputStream Resourceinputstream = Null;if (Contextclassloader! = null) {Resourceinputstream = Contextclassloader.getresourceasstream (resourceName);} if (Resourceinputstream = = null) {Resourceinputstream = Environment.class.getClassLoader (). getResourceAsStream ( resourcename);} if (Resourceinputstream = = null) {throw new Mappingnotfoundexception ("resource", resourcename);} Add (Resourceinputstream, "resource", resourcename); return this;}
This method functions relatively simple, through the class loader to open the input stream,
and forwards the input stream as an argument to add (Resourceinputstream, "resource", resourcename) to handle
Step 7.configuration.add
The method is defined in the Org/hibernate/cfg/configuration.java file
public void Add (XmlDocument metadataxml) {if (Insecondpass | |!isormxml (metadataxml)) {Metadatasourcequeue.add (Metada Taxml);} else {final Metadataprovider Metadataprovider = ((metadataproviderinjector) reflectionmanager). Getmetadataprovider () ; Jpametadataprovider Jpametadataprovider = (jpametadataprovider) Metadataprovider; list<string> classnames = Jpametadataprovider.getxmlcontext (). Adddocument (Metadataxml.getdocumenttree ()); for (String classname:classnames) {try {Metadatasourcequeue.add (Reflectionmanager.classforname (ClassName, this.getc Lass ()));} catch (ClassNotFoundException e) {throw new Annotationexception ("Unable to load class defined in XML:" + ClassName, E );}}}}
Add (InputSource InputSource, String origintype, String originname)
Add (InputSource InputSource, Origin origin)
Above two overloads of the Add () method, the calling procedure skips
In the Add (XmlDocument metadataxml) method, we can see that it has been handled as a delegate,
Given to the member Variable Metadatasourcequeue processing, Metadatasourcequeue is an Metadatasourcequeue instance, which is the inner class of the configuration
Step 8.metadatasourcequeue.add
The method is defined in the org/hibernate/cfg/ Configuration.java file
public void Add (XmlDocument metadataxml) {Final Document document = Metadataxml.getdocumenttree (); final Element Hmnode = Document.getrootelement (); Attribute Packnode = Hmnode.attribute ("package"); String Defaultpackage = Packnode! = null? Packnode.getvalue (): ""; set<string> entitynames = new hashset<string> () findclassnames (Defaultpackage, HmNode, EntityNames); for ( String entity:entitynames) {hbmmetadatabyentitynamexref.put (entity, metadataxml);}
This.hbmMetadataToEntityNamesMap.put (Metadataxml, entitynames);}
Metadataxml points to a document root node
findclassnames (Defaultpackage, Hmnode, Entitynames) method action:
Stores the name attribute of the class element in the entity mapping file in the local variable entitynames
The value of the Entitynames collection element is then used as the key, and the document root node is stored in the member variable hbmmetadatabyentitynamexref as value.
Hbmmetadatabyentitynamexref is map<string, xmldocument> instance
The document root node is the key, and the collection entitynames as value, stored in the member variable Hbmmetadatatoentitynamesmap,
Hbmmetadatatoentitynamesmap is an example of linkedhashmap<xmldocument, set<string>>,
Protected class Metadatasourcequeue implements Serializable {private linkedhashmap<xmldocument, set<string> > hbmmetadatatoentitynamesmap= new Linkedhashmap<xmldocument, set<string>> ();p rivate Map<String, xmldocument> hbmmetadatabyentitynamexref = new hashmap<string, xmldocument> ();//xclass is not serializable by defaultprivate transient list<xclass> annotatedclasses = new arraylist<xclass> ();//only used during the Secondphasecompile Pass, hence does not need to be serializedprivate transient map<string, xclass> annotatedclassesb Yentitynamemap = new hashmap<string, xclass> ();p rivate void ReadObject (ObjectInputStream ois) throws IOException, ClassNotFoundException {...} private void WriteObject (Java.io.ObjectOutputStream out) throws IOException {...} public void Add (XmlDocument metadataxml) {Final Document document = Metadataxml.getdocumenttree (); final Element Hmnode = d Ocument.getrootelement (); Attribute Packnode = Hmnode.aTtribute ("package"); String Defaultpackage = Packnode! = null? Packnode.getvalue (): ""; set<string> entitynames = new hashset<string> () findclassnames (Defaultpackage, HmNode, EntityNames); for ( String entity:entitynames) {hbmmetadatabyentitynamexref.put (entity, metadataxml);} This.hbmMetadataToEntityNamesMap.put (Metadataxml, Entitynames);}}
The storage structure of Hbmmetadatabyentitynamexref and Hbmmetadatatoentitynamesmap, 2 shows:
Figure 2: Storage structure of two maps
Hibernate source-configuration file loading process analysis