MyBatis Source Learning: Application of dynamic agent (slowly change)

Source: Internet
Author: User

Dynamic Agent Overview

When I was learning spring, I learned that using dynamic proxies to implement AOP is an introduction: you need to calculate the call time for all methods. It is possible to get the current time for each method start and end. Similar to this:

long current=system.currenttimemillis (); Call the original method long last=system.currenttimemillis ();

If each method is actually a bit uncomfortable to join, the dynamic agent appeared. The dynamic proxy rewrites the sub-code of the original corresponding class by using the bytecode technique, and adds the corresponding logic.

Mainstream dynamic agent implementation techniques are as follows: JDK and Cglib,javassist,asm refer to this.

Application of MyBatis

We know that in MyBatis, we just write the Mapper interface and interface corresponding to the Mapper.xml, use the following method to get the instance and call method. (code from MYBATIS3 comes with test cases)

Boundblogmapper mapper = Session.getmapper (boundblogmapper.  Class);

Blog B = mapper.selectblogwithpostsusingsubselect (1);
Assertequals (1, B.getid ());
Session.close ();

The mapper in this is the object of the proxy class that gets the interface boundblogmapper using the dynamic proxy method in the JDK. Concrete ways to see for yourself. Very easy to track. The most important thing about JDK dynamic agent is to implement

the processing of the Invocationhandler interface is tiring. The most severe calls are as follows. the most important Mappermethod.execute (sqlsession, args) in the Invoke method
1  Public classMapperproxy<t>ImplementsInvocationhandler, Serializable {2 3   Private Static Final LongSerialversionuid = -6424540398559729838l;4   Private Finalsqlsession sqlsession;5   Private FinalClass<t>Mapperinterface;6   Private FinalMap<method, mappermethod>Methodcache;7 8    PublicMapperproxy (sqlsession sqlsession, class<t> mapperinterface, Map<method, mappermethod>Methodcache) {9      This. sqlsession =sqlsession;Ten      This. Mapperinterface =Mapperinterface; One      This. Methodcache =Methodcache; A   } -  -    PublicObject Invoke (Object proxy, Method method, object[] args)throwsThrowable { the     if(Object.class. Equals (Method.getdeclaringclass ())) { -       Try { -         returnMethod.invoke ( This, args); -}Catch(Throwable t) { +         Throwexceptionutil.unwrapthrowable (t); -       } +     } A     FinalMappermethod Mappermethod =Cachedmappermethod (method); at     returnMappermethod.execute (sqlsession, args); -   } -  -   PrivateMappermethod Cachedmappermethod (method) { -Mappermethod Mappermethod =Methodcache.get (method); -     if(Mappermethod = =NULL) { inMappermethod =NewMappermethod (Mapperinterface, Method, Sqlsession.getconfiguration ()); - Methodcache.put (method, Mappermethod); to     } +     returnMappermethod; -   } the  *}

Different processing according to several types of operation

 PublicObject Execute (sqlsession sqlsession, object[] args) {object result; if(Sqlcommandtype.insert = =Command.gettype ()) {Object param=Method.convertargstosqlcommandparam (args); Result=Rowcountresult (Sqlsession.insert (Command.getname (), param)); } Else if(Sqlcommandtype.update = =Command.gettype ()) {Object param=Method.convertargstosqlcommandparam (args); Result=Rowcountresult (Sqlsession.update (Command.getname (), param)); } Else if(Sqlcommandtype.delete = =Command.gettype ()) {Object param=Method.convertargstosqlcommandparam (args); Result=Rowcountresult (Sqlsession.delete (Command.getname (), param)); } Else if(Sqlcommandtype.select = =Command.gettype ()) {      if(Method.returnsvoid () &&Method.hasresulthandler ())        {Executewithresulthandler (sqlsession, args); Result=NULL; } Else if(Method.returnsmany ()) {result=Executeformany (sqlsession, args); } Else if(Method.returnsmap ()) {result=Executeformap (sqlsession, args); } Else{Object param=Method.convertargstosqlcommandparam (args); Result=Sqlsession.selectone (Command.getname (), param); }    } Else if(Sqlcommandtype.flush = =Command.gettype ()) {Result=sqlsession.flushstatements (); } Else {      Throw NewBindingexception ("Unknown execution method for:" +command.getname ()); }    if(Result = =NULL&& Method.getreturntype (). isprimitive () &&!method.returnsvoid ()) {      Throw NewBindingexception ("Mapper method" +Command.getname ()+ "attempted to return null from a method with a primitive return type (" + method.getreturntype () + ")."); }    returnresult; }

 

MyBatis Source Learning: Application of dynamic agent (slowly change)

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.