The use and principle analysis of mapper mapping configuration in MyBatis Framework (vii) Mapperproxy,mapperproxyfactory

Source: Internet
Author: User
Tags throwable

The use and principle analysis of mapper mapping configuration in <mybatis framework above (vi) mapperregistry> We know the Getmapper method of Defaultsqlsession, Finally, the mapper instance is obtained through the Mapperregistry object:

 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); }  }  

From the code we see an attempt to remove mapperproxyfactory from a variable called knownmappers.

Let's look at the definition of this knownmapper in Mapperregistry:

Private Final New Hashmap<class<?>, mapperproxyfactory<?>> ();  

There are getmapper methods, then the inevitable Addmapper method:

 Public<T>voidAddmapper (class<t>type) {    if(Type.isinterface ()) {if(Hasmapper (type)) {Throw NewBindingexception ("type" + Type + "is already known to the Mapperregistry."); }      Booleanloadcompleted =false; Try{knownmappers.put (type,NewMapperproxyfactory<t>(type)); //It's important that the type was added before the parser is run//otherwise the binding may automatically is attempted by the//Mapper parser.  If the type is already known, it won ' t try. Mapperannotationbuilder parser =Newmapperannotationbuilder (config, type);        Parser.parse (); LoadCompleted=true; } finally {        if(!loadcompleted)        {knownmappers.remove (type); }      }    }  }  

Use and principle analysis of mapper mapping configuration in <mybatis Framework (iv) Parsing mapper interface map XML file > Article, parsing after playing XML, binding namespace Bindmapperfornamespace () method

//Binding to namespacesPrivate voidBindmapperfornamespace () {String namespace=Builderassistant.getcurrentnamespace (); if(Namespace! =NULL) {Class<?> Boundtype =NULL; Try{Boundtype=Resources.classforname (namespace); } Catch(ClassNotFoundException e) {//Ignore, bound type is not required    }    if(Boundtype! =NULL) {      if(!Configuration.hasmapper (Boundtype)) {        //Spring may isn't know the real resource name so we set a flag//To prevent loading again this resource from the Mapper interface//Look at mapperannotationbuilder#loadxmlresourceConfiguration.addloadedresource ("namespace:" +namespace);      Configuration.addmapper (Boundtype); }    }  }}

We see

Configuration.addmapper (Boundtype);

Just call the Mapperregistry.addmapper method

   Public void addmapper (class<t> type) {    mapperregistry.addmapper (type);  }

We look back at how Getmapper gets the Mapper object:

1. Get mapperproxyfactory First

2. Call the Newinstance method of the Mapperproxyfactory object to get the mapper.

Let's look at the Mapperproxyfactory code:

 Public T newinstance (sqlsession sqlsession) {    finalnew mapperproxy<t>(sqlsession , Mapperinterface, Methodcache);     return newinstance (mapperproxy);  }     protected T newinstance (mapperproxy<t> mapperproxy) {    returnnew  class[] { Mapperinterface}, Mapperproxy);  

This is the return of a proxy class instance mapperproxy.

 Packageorg.apache.ibatis.binding;Importjava.io.Serializable;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method;ImportJava.util.Map;ImportOrg.apache.ibatis.reflection.ExceptionUtil;Importorg.apache.ibatis.session.SqlSession;/** * @authorClinton Begin *@authorEduardo Macarron*/ Public classMapperproxy<t>ImplementsInvocationhandler, Serializable {Private Static Final LongSerialversionuid = -6424540398559729838l; Private Finalsqlsession sqlsession; Private FinalClass<t>Mapperinterface; Private FinalMap<method, mappermethod>Methodcache;  PublicMapperproxy (sqlsession sqlsession, class<t> mapperinterface, Map<method, mappermethod>Methodcache) {     This. sqlsession =sqlsession;  This. Mapperinterface =Mapperinterface;  This. Methodcache =Methodcache; }   PublicObject Invoke (Object proxy, Method method, object[] args)throwsThrowable {if(Object.class. Equals (Method.getdeclaringclass ())) {      Try {        returnMethod.invoke ( This, args); } Catch(Throwable t) {Throwexceptionutil.unwrapthrowable (t); }    }    FinalMappermethod Mappermethod =Cachedmappermethod (method); returnMappermethod.execute (sqlsession, args); }  PrivateMappermethod Cachedmappermethod (method) {Mappermethod Mappermethod=Methodcache.get (method); if(Mappermethod = =NULL) {Mappermethod=NewMappermethod (Mapperinterface, Method, Sqlsession.getconfiguration ());    Methodcache.put (method, Mappermethod); }    returnMappermethod; }}

To use a dynamic agent for Java, you have to implement the Invocationhandler interface:

@Override PublicObject Invoke (Object proxy, Method method, object[] args)throwsThrowable {Try {      if(Object.class. Equals (Method.getdeclaringclass ())) {        returnMethod.invoke ( This, args); } Else if(Isdefaultmethod (method)) {returnInvokedefaultmethod (proxy, method, args); }    } Catch(Throwable t) {Throwexceptionutil.unwrapthrowable (t); }    FinalMappermethod Mappermethod =Cachedmappermethod (method); returnMappermethod.execute (sqlsession, args); }  

The first thing to judge is whether the proxy object is an interface or a class, and obviously we do not have any implementation of the Mapper interface, then it will execute

Final Mappermethod Mappermethod = Cachedmappermethod (method);   return mappermethod.execute (sqlsession, args);  

Generates a Mappermethod object, then calls its Execute method, passes the sqlsession and arguments in, executes the Mapper method.

Use and principle analysis of mapper mapping configuration in MyBatis Framework (vii) Mapperproxy,mapperproxyfactory

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.