Mybatis source code analysis: MapperRegistry

mapper registrar (MapperRegistry)

   Registrar mapper for adding all of the interfaces to the memory mapper, Mapper register itself maintains two attributes, and config knownMappers, wherein knownMappers is a Class <?>, MapperProxyFactory <? > set, indicates that a path corresponding to the class the factory Mapper proxy, MapperProxyFactory do is relatively simple, the purpose is to create a model by proxy at a MapperProxy, MapperProxy realized InvocationHandler interface, which would represent MapperProxy method implementation calls the specified method Mapper interface via invoke (), MapperProxy not directly implement call Mapper interface, but internally sustains a <Mapper.Method, MapperMethod> of the map collection at the festival to see, MapperMethod related packaging method Sqlsession, so the MapperProxy essentially just a proxy <method, MapperMethod> mapping relationship between .

Folders Registry

MapperRegistry for registration, acquisition and determine whether Mapper interface has been registered functions, mainly provides several methods

1.getMapper (Class type, SqlSession sqlSession) acquired from the buffer corresponding to the set of interfaces Mapper
2.hasMapper (Class type) cache set is determined whether there is an interface Mapper
3.addMapper (Class type) was added to the interface Mapper collection knownMappers
4. getMappers () Gets knownMappers collection of all registered Mapper interfaces, Mybatis3.2.2 new
5.addMappers (String packageName, class <? > superType) Add all eligible superType subclasses under a package or a sub-interface Mybatis3.2.2 new

  Look addMapper () method, the main role of this method is to add Mapper to knownMappers set to achieve Mapper classes mapping Mapper proxy factory code has a very important, adding Mapper classes after collection to further must first be completed xml configure resolution, if the resolution fails, it will still mapper removed from the interface, follow-up will talk about how MapperAnnotationBuilder is resolved.

. 1  public <T> void addMapper (Class <T> type) {
 2        // determines whether the interface 
. 3      IF (type.isInterface ()) {
 . 4          // determines whether or not already registered 
. 5        IF (hasMapper (type)) {
 . 6          the throw  new new BindingException ( "the type" + type + "the IS already Known to MapperRegistry." );
 . 7        }
 . 8        Boolean LoadCompleted = to false ;
 . 9        the try {
 10            // the mapper to map the set of interface registers 
. 11          knownMappers.put (type, new MapperProxyFactory<T>(type));
12         // It's important that the type is added before the parser is run
13         // otherwise the binding may automatically be attempted by the
14         // mapper parser. If the type is already known, it won't try.
15         MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
16         parser.parse();
17         loadCompleted = true;
18       } finally {
19         if (!loadCompleted) {
20           knownMappers.remove(type);
21         }
22       }
23     }
24   }

getMapper(Class type, SqlSession sqlSession)

  If you get less than is used to instantiate a proxy factory Mapper MapperProxy, at the beginning we said, this is the ultimate goal of the method used to obtain Mapper already registered, acquisition mode directly from knownMappers collection, in order to obtain a MapperMethod that is, by way of example of the proxy factory, corresponding withdrawn mapper MapperProxyFactory, then instantiates the dynamic proxy mode ProxyMapper, the aim is to achieve a method of performing class of a proxy execution method of Mapper.

 

. 1 @SuppressWarnings ( "an unchecked" )
 2    public <T> T getMapper (Class <T> type, the SqlSession SQLSESSION) {
 . 3        the this .notifyAll ();
 . 4        // Get mapper proxy factory 
. 5      Final MapperProxyFactory <T> = mapperProxyFactory (MapperProxyFactory <T> ) knownMappers.get (type);
 . 6      // in the map is not found in said register does not come in the mapper class, is thrown BindingException 
. 7      IF (mapperProxyFactory == null ) {
 . 8        the throw  new new BindingException ( "the type" + + of the type "IS not Known to at The MapperRegistry." );
 9     }
10     try{
 11          // use the factory to create an instance, the agent essentially occurs by creating a proxy class model, creating an exception is thrown during BindingException 
12 is        return mapperProxyFactory.newInstance (SQLSESSION);
 13 is      } the catch (Exception E) {
 14        the throw  new new BindingException ( "Error Getting the Cause Mapper instance:." + E, E);
 15      }

 

MapperProxy

  mapperProxy should be counted as a wrapper class, itself does nothing, its main role is to maintain the <Method, MapperMethod> collection, so mapper interfaces will know what is about to execute SQL statements, and then commissioned inquiry to Sqlsession a. See the following code, the code execution flow is:

1. The proxy class is determined whether the class where the method, if it is, the direct implementation of the method.
2. The method determines whether the mode, if the default method is performed, whether it is the default method of determining the following conditions

 

(method.getModifiers()
     & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) == Modifier.PUBLIC
     && method.getDeclaringClass().isInterface()

3. If none of the above two, then removed from the corresponding set of cached MapperMethod, wherein the execute method is called.

  It should be noted that, invokeDefaultMethod () method using the @ UsesJava7 annotation indicates the minimum version should be used JDk7, the reason is because of the use MethodHandlers , this class follow-up will explain, now just need to know it is the same with reflection and can be called method.

. 1  @Override
 2    public Object Invoke (Object Proxy, Method Method, Object [] args) throws the Throwable {
 . 3      the try {
 . 4          // determine whether the proxy class is a class where Method 
. 5        IF (Object. Class .equals (method.getDeclaringClass ( ))) {
 6            // perform the method 
. 7          return Method.invoke ( the this , args);
 . 8        } // determine whether it is the default method 
. 9        the else  iF (isDefaultMethod (method)) {
 10            // call the default method 
. 11          returninvokeDefaultMethod (Proxy, Method, args);
 12 is        }
 13 is      } the catch (the Throwable T) {
 14        the throw ExceptionUtil.unwrapThrowable (T);
 15      }
 16      // removed from the cache corresponding method mapperMethod 
. 17      Final MapperMethod mapperMethod = cachedMapperMethod (Method) ;
 18      // execute execute () method 
. 19      return mapperMethod.execute (SQLSESSION, args);
 20 is    }
 1  @UsesJava7
 2   private Object invokeDefaultMethod(Object proxy, Method method, Object[] args)
 3       throws Throwable {
 4     final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class
 5         .getDeclaredConstructor(Class.class, int.class);
 6     if (!constructor.isAccessible()) {
 7       constructor.setAccessible(true);
 8     }
 9     final Class<?> declaringClass = method.getDeclaringClass();
10     return constructor
11         .newInstance(declaringClass,
12             MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
13                 | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC)
14         .unreflectSpecial(method, declaringClass)
15         .bindTo(proxy)
16         .invokeWithArguments(args);
17   }

 

The summary of MapperRegistry

  Register for the MapperRegistry essentially Mapper interfaces and access MapperProxy class, MapperProxy and instantiated by MapperProxyFactory, however MapperProxy the invoke () method calls execute () method MapperMethod Mapper classes in the interface corresponding thereto. MapperRegistry Mapper classes depends on the path, the SqlSession as the reference, binding MapperProxy, MapperProxyFactory, ResolverUtil, MapperAnnotationBuilder other components to complete a registration Mapper sql statement to execute the trip.

The following figure shows the associated class MapperRegistry

 

Guess you like

Origin www.cnblogs.com/zhengzuozhanglina/p/11234690.html