Hibernate source code-configuration file Loading Process Analysis

Source: Internet
Author: User

Hibernate source code-configuration file Loading Process Analysis

Hibernate suggests that Configuration and SessionFactory are Singleton in an application system, and Session is multiple.

When we execute the following code, hibernate starts to load the default configuration file.

new Configuration().configure()

Hibernate searches for the configuration file "hibernate. cfg. xml" in the root path of classath and parses it, as shown in process 1.


Figure 1: sequence of configuration file loading


Next we will analyze the configuration file loading process.

Step 1. Configuration. configure ()

This method is defined in the org/hibernate/cfg/Configuration. java file.

public Configuration configure() throws HibernateException {configure( "/hibernate.cfg.xml" );return this;}

Call the overload method configure ("/hibernate. cfg. xml") and pass in the default configuration file name as the real parameter.


Step 2. Configuration. doConfigure

This 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_NAME, name );}addProperties( sfNode );parseSessionFactory( 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 transfers the configuration loading process to two indirect layer methods for processing. addProperties () and parseSessionFactory


Step 3. Configuration. addProperties

This method is defined in the org/hibernate/cfg/Configuration. java file.

private void addProperties(Element parent) {Iterator itr = parent.elementIterator( "property" );while ( itr.hasNext() ) {Element node = (Element) itr.next();String name = node.attributeValue( "name" );String value = node.getText().trim();log.debug( name + "=" + value );properties.setProperty( name, value );if ( !name.startsWith( "hibernate" ) ) {properties.setProperty( "hibernate." + name, value );}}Environment.verifyProperties( properties );}


This method parses the content of the property element in the configuration file and stores it in the properties member variable. properties is a Properties instance,

In the if condition, it is found that if the value of name does not start with "hibernate", it is automatically completed.


  
   
    
    
     
True
    
    
    
     
Oracle. jdbc. driver. OracleDriver
    
    
     
Jdbc: oracle: thin: @ 127.0.0.1: 1521: orcl
    
    
     
Diankun
    
    
     
Diankun
     
     
    
     
Org. hibernate. dialect. Oracle10gDialect
    
    
    
     
Update
    
    
    
    
    
    
   
  


Step 4. Configuration. parseSessionFactory

This method is defined in the org/hibernate/cfg/Configuration. java file.

private void parseSessionFactory(Element sfNode, String name) {Iterator elements = sfNode.elementIterator();while ( elements.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 );}}}

The sfNode parameter points to the session-factory element node.
The parameter name is the name attribute value of session-factory, which is equal to null.

The following configuration is added to the configuration file:

  
  
  
  

The branch that meets the condition "" mapping ". equals (subelementName )"


Step 5. Configuration. parseMappingElement

This 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 = resourceAttribute.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( "
  
    element in configuration specifies no known attributes" );}}
  

We configure in hibernate. cfg. xml ,

Qualified resourceAttribute! = Null, call the addResource (resourceName) Method


Step 6. Configuration. addResource

This 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 is simple. You can use the class loader to enable the input stream,

And forward the input stream to add (resourceInputStream, "resource", resourceName) for processing.


Step 7. Configuration. add

This method is defined in the org/hibernate/cfg/Configuration. java file.

public void add(XmlDocument metadataXml) {if ( inSecondPass || !isOrmXml( metadataXml ) ) {metadataSourceQueue.add( metadataXml );}else {final MetadataProvider metadataProvider = ( (MetadataProviderInjector) reflectionManager ).getMetadataProvider();JPAMetadataProvider jpaMetadataProvider = ( JPAMetadataProvider ) metadataProvider;List
  
    classNames = jpaMetadataProvider.getXMLContext().addDocument( metadataXml.getDocumentTree() );for ( String className : classNames ) {try {metadataSourceQueue.add( reflectionManager.classForName( className, this.getClass() ) );}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)

The add () method is reloaded on the above two, and the call process is skipped.

In the add (XmlDocument metadataXml) method, we can see that it is used as a delegate,

It is handed over to the member variable metaperformancequeue for processing. metaperformancequeue is a metaperformancequeue instance and is the internal class of Configuration.


Step 8. metaperformancequeue. add

This 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
  
    entityNames = new HashSet
   
    ();findClassNames( defaultPackage, hmNode, entityNames );for ( String entity : entityNames ) {hbmMetadataByEntityNameXRef.put( entity, metadataXml );}this.hbmMetadataToEntityNamesMap.put( metadataXml, entityNames );}
   
  

MetadataXml points to a document root node

Function of the findClassNames (defaultPackage, hmNode, entityNames) method:

Stores the name attribute of the class Element in the object ing file in the entityNames local variable.

The value of the element in the entityNames set is used as the key, and the document root node is used as the value, which is stored in the member variable hb1_adatabyentitynamexref,

Hb1_adatabyentitynamexref is Map Instance


Use the document root node as the key, and set entityNames as the value, which is stored in the member variable hb1_adatatoentitynamesmap,

HbmMetadataToEntityNamesMap is LinkedHashMap > Instance,


protected class MetadataSourceQueue implements Serializable {private LinkedHashMap
  
   > hbmMetadataToEntityNamesMap= new LinkedHashMap
   
    >();private Map
    
      hbmMetadataByEntityNameXRef = new HashMap
     
      ();//XClass are not serializable by defaultprivate transient List
      
        annotatedClasses = new ArrayList
       
        ();//only used during the secondPhaseCompile pass, hence does not need to be serializedprivate transient Map
        
          annotatedClassesByEntityNameMap = new HashMap
         
          ();private 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 = document.getRootElement();Attribute packNode = hmNode.attribute( "package" );String defaultPackage = packNode != null ? packNode.getValue() : "";Set
          
            entityNames = new HashSet
           
            ();findClassNames( defaultPackage, hmNode, entityNames );for ( String entity : entityNames ) {hbmMetadataByEntityNameXRef.put( entity, metadataXml );}this.hbmMetadataToEntityNamesMap.put( metadataXml, entityNames );}}
           
          
         
        
       
      
     
    
   
  



The storage structure of hb1_adatabyentitynamexref and hb1_adatatoentitynamesmap, as shown in Figure 2:


Figure 2: storage structure of two maps



Related Article

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.