How the Mapper (DAO layer) interface is instantiated

Source: Internet
Author: User

The MyBatis map file loading is an analysis of how all of our XML mapping files are loaded, but in the process of learning SSM, I find that the interface of the DAO layer will inject an instantiated object into the service layer directly, but we do not do the DAO layer implementation class,

Very curious to check the information, the following analysis

MyBatis configuration file

MyBatis is implemented by the Org.mybatis.spring.mapper.MapperScannerConfigurer class to implement the DAO layer scan we enter the Mapperscannerconfigurer class, There is a Postprocessbeandefinitionregistry method

   Public voidPostprocessbeandefinitionregistry (Beandefinitionregistry registry) {if( This. Processpropertyplaceholders)    {processpropertyplaceholders (); } Classpathmapperscanner Scanner=NewClasspathmapperscanner (registry); Scanner.setaddtoconfig ( This. Addtoconfig); Scanner.setannotationclass ( This. Annotationclass); Scanner.setmarkerinterface ( This. Markerinterface); Scanner.setsqlsessionfactory ( This. sqlsessionfactory); Scanner.setsqlsessiontemplate ( This. sqlsessiontemplate); Scanner.setsqlsessionfactorybeanname ( This. Sqlsessionfactorybeanname); Scanner.setsqlsessiontemplatebeanname ( This. Sqlsessiontemplatebeanname); Scanner.setresourceloader ( This. ApplicationContext); Scanner.setbeannamegenerator ( This. Namegenerator);        Scanner.registerfilters (); //Scan all DAO interfaces under the Basepackage packageScanner.scan (Stringutils.tokenizetostringarray ( This. Basepackage, configurableapplicationcontext.config_location_delimiters)); }

Enter the Doscan method

// The parent class finds the Qualifying interface class and transforms it into a bean class Super . Doscan (basepackages); if (Beandefinitions.isempty ()) {  Logger.warn ("No MyBatis Mapper is found in '" + arrays.tostring ( basepackages) + "' package. Please check your configuration. "  Else  {// processing the found interface Bean class   processbeandefinitions ( beandefinitions);} return beandefinitions;

And look at the Processbeandefinitions method.

Private voidProcessbeandefinitions (set<beandefinitionholder>beandefinitions)    {genericbeandefinition definition;  for(beandefinitionholder holder:beandefinitions) {definition=(genericbeandefinition) holder.getbeandefinition (); if(logger.isdebugenabled ()) {Logger.debug ("Creating Mapperfactorybean with Name" +Holder.getbeanname ()+ "' and '" + definition.getbeanclassname () + "' Mapperinterface"); }      //The Mapper interface is the original class of the Bean//but, the actual class of the beans is MapperfactorybeanDefinition.getconstructorargumentvalues (). Addgenericargumentvalue (Definition.getbeanclassname ());//Issue #59

Set the Beanclass type to Mapperfactorybean definition.setbeanclass ( This. Mapperfactorybean.getclass ()); Definition.getpropertyvalues (). Add ("Addtoconfig", This. Addtoconfig); Booleanexplicitfactoryused =false; if(Stringutils.hastext ( This. Sqlsessionfactorybeanname)) {definition.getpropertyvalues (). Add ("Sqlsessionfactory",NewRuntimebeanreference ( This. Sqlsessionfactorybeanname)); Explicitfactoryused=true; } Else if( This. sqlsessionfactory! =NULL) {definition.getpropertyvalues (). Add ("Sqlsessionfactory", This. sqlsessionfactory); Explicitfactoryused=true; } if(Stringutils.hastext ( This. Sqlsessiontemplatebeanname)) { if(explicitfactoryused) {Logger.warn ("Cannot use Both:sqlsessiontemplate and sqlsessionfactory together. Sqlsessionfactory is ignored. "); } definition.getpropertyvalues (). Add ("Sqlsessiontemplate",NewRuntimebeanreference ( This. Sqlsessiontemplatebeanname)); Explicitfactoryused=true; } Else if( This. sqlsessiontemplate! =NULL) { if(explicitfactoryused) {Logger.warn ("Cannot use Both:sqlsessiontemplate and sqlsessionfactory together. Sqlsessionfactory is ignored. "); } definition.getpropertyvalues (). Add ("Sqlsessiontemplate", This. sqlsessiontemplate); Explicitfactoryused=true; } if(!explicitfactoryused) { if(logger.isdebugenabled ()) {Logger.debug ("Enabling Autowire by type for Mapperfactorybean with Name '" + holder.getbeanname () + "'."); } definition.setautowiremode (Abstractbeandefinition.autowire_by_type); } } }

The DAO layer interface will eventually be packaged into Mapperfactorybean

That is to say, we will be all the DAO layer files, encapsulated into the following configuration file the same effect, is not very familiar with

class= "Org.mybatis.spring.mapper.MapperFactoryBean" >        <property name= "Mapperinterface" value= " Com.zsh.dao.UserMapper "></property>        <property name=" sqlsessionfactory "ref=" sqlsessionfactory "/ ></bean>

The above is the principle of scanning the DAO layer, we continue to analyze how to instantiate the interface automatically

Again, before we instantiate the interface automatically, we know what it is. Dynamic proxy analysis and extension of dynamic agent mechanism

The above is a factory method to create the bean
First we locate the class Org.mybatis.spring.mapper.MapperFactoryBean

 Public class extends Implements         Factorybean<T> {    private class<t> mapperinterface;     Private boolean addtoconfig;

You can see that the class implements the Org.springframework.beans.factory.FactoryBean interface by invoking the
Org.mybatis.spring.mapper.MapperFactoryBean.getObject () method to get the bean

     Public throws Exception {        return getsqlsession (). Getmapper (this. mapperinterface);    

We analyze the above getsqlsession () can see Getmapper implementation class is sqlsessiontemplate, we jump to sqlsessiontemplate look at Getmapper method

     public <T> T getmapper (class<t> type) {        return this );    }

As you can see, it first calls its own getconfiguration () method to return a configuration object and then calls the Getmapper method of the Configuration object.

We directly navigate to the Getmapper method of the configuration

   public <T> T getmapper (class<t> type, sqlsession sqlsession) {    return  Mapperregistry.getmapper (type, sqlsession);  }

Navigate directly to Mapperregistry.getmapper

   Public<T> T Getmapper (class<t>type, sqlsession sqlsession) {    FinalMapperproxyfactory<t> mapperproxyfactory = (mapperproxyfactory<t>) Knownmappers.get (type); if(Mapperproxyfactory = =NULL) {      Throw NewBindingexception ("type" + Type + "is not known to the Mapperregistry.")); }    Try {      returnmapperproxyfactory.newinstance (sqlsession); } Catch(Exception e) {Throw NewBindingexception ("Error getting mapper instance. Cause: "+e, E); }  }

In this method, first obtain a Mapperproxyfactory object mapperproxyfactory, and then call the object's Newinstance method to create the bean we need, navigate to the Newinstance method

   Public T newinstance (sqlsession sqlsession) {    finalnew mapperproxy<t>(sqlsession , Mapperinterface, Methodcache);     return newinstance (mapperproxy);  }

Finally we go into the newinstance this overloaded function

protected T newinstance (mapperproxy<t> mapperproxy) {    returnnew  class[] { Mapperinterface}, Mapperproxy);  }

In this case, we created a proxy object with the JDK's dynamic proxy, that is, we finally created our own proxy object for all the interfaces of mapper, and executed our SQL through proxy objects.

Reference and thanks

Https://www.cnblogs.com/question-sky/p/6654101.html

http://blog.csdn.net/tanqidong1992/article/details/48026491

Https://www.jianshu.com/p/3e619786dd18

How the Mapper (DAO layer) interface is instantiated

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.