MyBatis Source Analysis (i)--mapper dynamic agent __mybatis

Source: Internet
Author: User
Tags aop throwable

CSDN reading effect is not as good as personal blog, suggest or read blog, flexor ' s blog

Most of the work is mybatis this semi-automatic ORM framework, with a long time but to its understanding is not very deep, so I intend to open a series of articles on its interpretation, by the way of the knowledge to check the leak fill. This is a detailed explanation of the principle of mapper dynamic agent. proxy Mode definition

Provides an alias or placeholder for another object to control access to the object. That is, the objective is to control the object form its responsibilities. Of course, it can also enhance its responsibilities, such as spring AOP. proxy mode class diagram

As shown in the following illustration, the role required for agent mode is:
1. External behavior interface subject, for caller client visible
2. Realsubject true subject, which contains specific interface behavior, not visible to client
3. Proxy class proxy, which is the realsubject of the double, can also be treated as a layer of realsubject packaging, for the client is not visible.
JDK Dynamic Proxy example

The case takes the Java dynamic Proxy form development, defines the role according to the above class diagram
Subject

Public interface Subject {
  /**
   * Inversion input string
   * @param input to reverse string
   * @return the
  string/String Reversalinput (String input);
}

Realsubject

public class Realsubject implements Subject {public

  string reversalinput (String input) {
    System.out.println (" I am Realsubject: "+input";
    return new StringBuilder (input). reverse (). toString ();

Subjectproxy
This class implements the Invocationhandler, in fact is to intercept the call, intercept and then turn to the real object of the call, so as to get the correct results. Is it much like the decorator pattern? In fact, it can be understood that the design pattern itself has a lot of relevance, There is no need to identify a behavior is a single pattern, from the effect of the subjectproxy is actually the decoration of realsubject, but this decoration does not add new features.

public class Subjectproxy implements Invocationhandler {

  private Object target;

  Public Subjectproxy (Object target) {
    this.target = target;
  }

  public object Invoke (Object Proxy, Method method, object[] args) throws Throwable {
    System.out.println ("Proxy subject Is "+proxy.getclass ());
    SYSTEM.OUT.PRINTLN ("Real Subject:" +tostringbuilder.reflectiontostring (target));
    System.out.println ("Method:" +method);
    System.out.println ("args:" + tostringbuilder.reflectiontostring (args));
    Return Method.invoke (target, args);
  }

Client

public class Client {public

  static void Main (string[] args) {
    realsubject subject = new Realsubject ();

    Subject proxyinstance = (Subject) proxy.newproxyinstance (
        Subject.class.getClassLoader (),
        new class[]{ Subject.class},
        new Subjectproxy (Subject));

    System.out.println (Proxyinstance.reversalinput ("Hello World"));
  }

Output

Proxy is class Com.sun.proxy. $Proxy 0
Target proxy:cn.mrdear.proxy.realsubject@51016012[]
method:public Abstract java.lang.String cn.mrdear.proxy.Subject.reversalInput (java.lang.String)
args: [ljava.lang.object;@ 29444d75[{hello World}]
I'm Realsubject:hello world
dlrow Olleh

Analysis
1. Where dynamic agents reflect the dynamic?

A. java file is required for general Java class variable creation and is then compiled into a. class file, and the virtual machine loads the. class file before the object can be built. But for subject proxyinstance the proxy class does not exist. java files, That is, the. class file for that object is dynamically generated, and then the virtual machine loads the class file and creates the object. In Proxy.java, there are the following code to dynamically generate class files, interested in the words can be studied, there is not much depth.

            
             * * Generate the specified proxy class.
             * *
            byte[] proxyclassfile = Proxygenerator.generateproxyclass (Proxyname, interfaces, AccessFlags);

Requirements for 2.JDK dynamic agents

JDK dynamic Proxy can only be for the interface, if you want to target the common class is to consider the implementation of Cglib, there is not much analysis. Second, the requirement of dynamic Proxy has interface class Subject,invocationhandler Proxy method class exists to create proxy object, The execution method of the proxy object is intercepted by the Invocationhandler interface, to the execution of the real class or the operation you want. Dynamic mapper of MyBatis

From the above, we can see that the JDK dynamic proxy needs the interface, the real implementation class, the Clinet caller, in the regular MyBatis Mapper proxy interface is the mapper,client is the service, then the real implementation class is what? Obviously this is the key point of the mapper agent. mapperproxyfactory

As the name suggests that this class is the production of Mapper interface of the factory class, its internal has the following methods, which can be seen Mapperproxy is the method of interception, then to this dynamic agents need to be the role of all together, then the next analysis of the most important Mapperproxy method to intercept.

Protected T newinstance (mapperproxy<t> mapperproxy) {return
    (t) proxy.newproxyinstance ( Mapperinterface.getclassloader (), new class[] {mapperinterface}, mapperproxy);
  
Mapperproxy

This class is the proxy role of the Mapper interface, inherits the Invocationhandler, so has the method interception function, looks at the code annotation.

  @Override Public
  object Invoke (Object proxy, Method method, object[] args) throws Throwable {
    try {
      if (object . Class.equals (Method.getdeclaringclass ()) {////Determines whether it is object because it is not an interface return
        Method.invoke (this, args);
      else if (Isdefaultmethod (method)) {//To determine whether the default method is the total interface, JDK8 allows the default method to be declared in the interface.
        Return Invokedefaultmethod (proxy, method, args);
      }
    catch (Throwable t) {
      throw exceptionutil.unwrapthrowable (t);
    }
    Processing of the normal mapper request
    final Mappermethod Mappermethod = Cachedmappermethod (method);
    Return Mappermethod.execute (sqlsession, args);
  }

For a method call in the normal mapper interface, MyBatis will move to execute in the Mappermethod Execute method, where the result is returned to the caller client, and the entire agent process ends. There is caching for normal calls, And the proxy class is generated when the project is started, for the performance impact is not very practical or very high.

Here to note that for the default interface method processing Invokedefaultmethod (proxy, method, args), which directly generate a proxy class each time, the performance is a loss should not be small, so it is not recommended to write the default method in the Mapper interface .

  @UsesJava7
  Private Object Invokedefaultmethod (object proxy, Method method, object[] args)
      throws Throwable {
    Final Constructor<methodhandles.lookup> constructor = MethodHandles.Lookup.class
        . Getdeclaredconstructor (Class.class, int.class);
    if (!constructor.isaccessible ()) {
      constructor.setaccessible (true);
    }
    Final class<?> Declaringclass = Method.getdeclaringclass ();
    Return constructor
        . newinstance (Declaringclass,
            MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
                | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC)
        . Unreflectspecial (method, Declaringclass). BindTo (proxy). Invokewitharguments ( args);
  }
Summary

The biggest benefit of dynamic proxies from above is that interfaces (not just Java interface, but also dynamic proxy implementations of Cglib) are decoupled from their implementation classes, where interfaces and dynamic classes are strongly correlated, interfaces cannot be instantiated, and implementation classes must implement all the methods of the interface, With a dynamic proxy, the relationship between the interface and the implementation class is not very large, even without the need to implement the class to complete the call, such as MyBatis, which does not create the implementation class of the interface, but instead uses a method interceptor to turn to its own common processing logic. The
is also the dynamic proxy for spring AOP, which naturally enhances the 0 intrusion of the original method and its code.
Finally mybatis Mapper Dynamic Proxy Implementation principle is very clear, the next specific analysis Mappermethod, by the way learning mybatis various design patterns.

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.