MYBATIS3 Source Analysis (-mapper) Implementation-Dynamic agent _mapperproxy

Source: Internet
Author: User
Tags throwable

When defining a Mapper interface (Userdao), we do not need to implement this class, but Sqlsession.getmapper () eventually returns an object that implements the interface. This object is implemented by MyBatis using the dynamic proxy of JDK. Here we will introduce the generation process of this proxy object and the implementation process of its method. The mapper code object's build Process Defaultsqlsession.getmapp () method will eventually invoke the Mapperregistry.getmapper () method [java]  View Plain  copy Public <t> t getmapper (class<t> type, sqlsession sqlsession)  {       //This mapperproxyfactory is the,      that is added to the knownmappers when the Addmapper method is invoked.  final MapperProxyFactory<T> mapperProxyFactory =  (mapperproxyfactory<t>)  knownmappers.get (type);      if  (mapperproxyfactory == null)         //indicates that the Mapper interface is not registered         throw  new bindingexception ("type "  + type +  " is not known  To the mapperregistry. ");       try {         //generates a Mapperproxy object         return  Mapperproxyfactory.newinstance (sqlsession);      } catch  (exception e)  {        throw new bindingexception ("error getting  mapper instance. Cause:  " + e, e);      }     }   Below is the Newinstance method of mapperproxyfactory [java]  view plain  copy public t  Newinstance (sqlsession sqlsession)  {       //creates a Mapperxy object, This method implements the Invocationhandler interface in the JDK dynamic proxy        final MapperProxy<T>  Mapperproxy = new mapperproxy<t> (Sqlsession, mapperinterface, methodcache);        return newinstance (mapperproxy);     }      protected t  newinstance (mapperproxy<t> mapperproxy)  {       // Mapperinterface, the Mapper interface is represented, the object returned is a subclass of the Mapper interface, and the method is called to be Mapperproxy intercepted, that is, to execute the Mapperproxy.invoke () method         return  (T)  proxy.newproxyinstance (Mapperinterface.getclassloader (),  new class[] { mapperinterface }, mapperproxy);     }    Mapperproxy Detailed analysis Mapperproxy [java]  view plain  copy public class mapperproxy<t>& nbsp;implements invocationhandler, serializable {        private  static final long serialVersionUID = -6424540398559729838L;      private final SqlSession sqlSession;        //mapper Interface       private final Class<T> mapperInterface;         //mapper each square in the interfaceThe FA will generate a Mappermethod object,  methodcache maintain their correspondence      // This methodcache is held in Mapperproxyfactory, Mapperproxyfactory is held in configuration      // So each mapper interface class corresponding to the Mapperproxyfactory and Methodcache is shared throughout the application, and generally there will only be one instance      private final  Map<Method, MapperMethod> methodCache;        public  Mapperproxy (sqlsession sqlsession, class<t> mapperinterface, map<method,  Mappermethod> methodcache)  {       this.sqlSession =  sqlsession;                  this.mapperinterface = mapperinterface;       this.methodcache =  methodCache;     }           //This will intercept the Mapper interface ( Userdao) of all Methods      public object invoke (ObJect proxy, method method, object[] args)  throws Throwable {        //If it is a method defined in object, execute directly. such as ToString (), hashcode () wait.        if  (Object.class.equals (Method.getdeclaringclass ())  {          try {            return method.invoke (This, args);         } catch   (throwable t)  {           throw  Exceptionutil.unwrapthrowable (t);         }        }       //Other methods of Mapper interface definition are assigned to Mappermethod for execution.        final mappermethod mappermethod = cachedmappermethod ( method);       return mappermethod.execute (sqlsesSion, args);     }        private MapperMethod  Cachedmappermethod (Method method)  {       MapperMethod  Mappermethod = methodcache.get (method);       if  (Mappermethod  == null)  {         mapperMethod = new  Mappermethod (Mapperinterface, method, sqlsession.getconfiguration ());          methodcache.put (Method, mappermethod);       }       return mapperMethod;     }     }   
Mappermethod [java]  View Plain  copy//All Mapper interfaces The method is invoked, and this method is executed. This is actually a method to invoke sqlsession Public object execute (Sqlsession sqlsession, object[] args)  {      Object result;     //This method is judged by the SQL type in the annotation      if  ( Sqlcommandtype.insert == command.gettype ())  {       //Execute INSERT        object param = method.convertargstosqlcommandparam (args);        result = rowcountresult (Sqlsession.insert (Command.getname),  param);     } else if  (sqlcommandtype.update ==  Command.gettype ())  {       //Executive update        Object param = method.convertargstosqlcommandparam (args);        Result = rowcountresuLt (Sqlsession.update (Command.getname (),  param));     } else if  ( Sqlcommandtype.delete == command.gettype ())  {       /delete        object param = method.convertargstosqlcommandparam (args);        result = rowcountresult (Sqlsession.delete (Command.getname (),  param);     } else if  (Sqlcommandtype.select == command.gettype ()) )  {       //select&nbsp, query        if  ( Method.returnsvoid ()  && method.hasresulthandler ())  {          //has no return value and has Resulthandler           Executewithresulthandler (Sqlsession, args);         result =  null;       } else if  (Method.returnsmany ())  {         / /Return to a list         result = executeformany (sqlSession,  args);       } else if  (Method.returnsmap ())  {         //returns a map         result =  executeformap (Sqlsession, args);       } else {         //returns an object          object param  = method.convertargstosqlcommandparam (args);         result  = sqlsession.selectone (Command.getname (),  param);       }      } else {       throw new bindingexception (" unknown execution method for:  " + command.getname ());     }     if  (Result == null && method.getreturntype (). Isprimitive ()   && !method.returnsvoid ())  {       throw new  Bindingexception ("mapper method  '"  + command.getname ()              +  " attempted to return null from a  method with a primitive return type  (" + method.getreturntype ()  +   ").");      }     return result;  }  
Summary in the programming interface provided by MyBatis, developers need only define mapper interfaces (such as: Userdao), which developers do not need to implement. MyBatis uses JDK's dynamic proxies to implement the Mapper interface. In MyBatis, each mapper interface corresponds to a Mapperproxyfactory object instance, which corresponds to the Configuration.mapperRegistry.knownMappers. When the Getmapper () method is invoked, MyBatis finds the corresponding Mapperproxyfactory object instance, using the factory to create a JDK dynamic proxy object, which is the implementation class for this mapper interface, when the method defined by mapper is invoked, Will invoke Mapperproxy to process it. Mapperproxy will find the corresponding Mappermethod object according to the method to implement this call. The mappermethod corresponds to the annotation in the method, the corresponding Mappedstatement object is found from the configuration, and then executed.

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.