The first three chapters have summarized the basic features, common configurations and mapper of Mybatis in detail. Compared with Hibernate, the configuration of mapper is relatively complex, but it has good flexibility and expansibility and can deal with various business scenarios. Master these contents, you can use MyBatis to develop smoothly.

I will introduce the analysis and operation principle of MyBatis as well as the custom plug-in. Today, I have read this part of the book, which will involve the basis of reflection and dynamic proxy. This article summarizes these for the convenience of understanding the principle.

Article Index:

  1. Introduction to JDBC and MyBatis
  2. All configurations of MyBatis
  3. Mapper knows all about it
  4. Reflection and dynamic proxy fundamentals

Through this introduction, you will know:

  • What problems do reflection and dynamic proxies solve
  • Class object
  • What does reflection do
  • Dynamic proxy implementation: JDK dynamic proxy, CGLIB

Understand reflection and dynamic proxies

reflection

Let’s take a look at the official definition of reflection:

You can use Java code to obtain information about fields, methods, and constructors of the currently loaded class, and use reflection fields, methods, and constructors to operate within security limits.

In simple terms, member information for each type in the program can be obtained at run time. The types of objects defined in a program are determined at compile time, whereas reflection can dynamically create objects and access or call their members.

A dynamic proxy

The so-called agent is a person or organization on behalf of another person or organization to do things, there are mainly three roles: visitor, agent, agent, the visitor through the agent, and agent interaction, will add some of their own processing.

Dynamic proxy means that you do not define proxy classes at compile time, but create them at run time. This is key: create proxy classes at run time.

Class object

The Class Class is an actual Class that exists in the java.lang package and represents runtime type information. The Class object represents the type information of a custom Class. For example, if you create a User Class, the JVM creates a Class object corresponding to the User Class. This object is stored in the JVM heap as an interface to access the User type information in the method area.

When using a custom Class, the Class object is first checked to see if it has been loaded. If not, the default Class loader first looks for the.class file based on the Class name, and the Class object is loaded into memory.

Class objects can be obtained in three ways:

  • Use the forName static method of Class;
  • Get the class of an object directly;
  • Call the getClass() method of an object;

The Class object is the basis for reflection and provides methods for retrieving Class information, as described below.

Function provided by reflection

The Java Reflection framework provides the following:

  • Determine the class to which an object belongs at run time;
  • Create objects at runtime;
  • At runtime, the class contains member variables, methods, parent classes, interfaces, and other information;
  • Calling a method of an object at runtime;

The following examples illustrate related functions

Create instance:

// Get the Class object corresponding to StringClass<? > c = User.class;// Get a constructor for the String class that takes a String argument
Constructor constructor = c.getConstructor(String.class);
// Create an instance from the constructor
User user = (User)constructor.newInstance("calm");
Copy the code

Obtaining method:

// Returns all methods declared by a class or interface, including private but not inherited methods
public Method[] getDeclaredMethods() throws SecurityException

// All public methods, including inherited methods
public Method[] getMethods() throws SecurityException

// Return a specific method. The first argument is the name of the method and the following arguments are the Class objects corresponding to the method arguments
public Method getMethod(String name, Class
       ... parameterTypes)

Copy the code

Call method:

Class<? > userClass=User.class; Object obj = userClass.newInstance(); Method method =klass.getMethod("addRole",String.class);
method.invoke(obj,"Super Administrator");
Copy the code

JDK dynamic proxy

The JDK itself provides an implementation of dynamic proxies that requires the proxyed to implement the interface.

public static Object newProxyInstance(ClassLoader loader, Class
       [] interfaces,InvocationHandler h)
Copy the code

The first argument is the classloader, the second argument is the list of interfaces implemented by the proxy, and the third argument is the object that implements the InvocationHandler interface.

InvocationHandler is an interface for specifying methods that execute the proppant, adding common processing code before and after the method is executed. The generated dynamic proxy class contains an InvocationHandler property that triggers a call to the Invoke method when the corresponding method is called.

public class JDKProxy implements InvocationHandler {    
    
    private Object targetObject;// Proxy object
    
    public Object newProxy(Object targetObject) {        
        this.targetObject = targetObject;     
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}    
    
    public Object invoke(Object proxy, Method method, Object[] args)/ / invoke method
            throws Throwable {    
        Object ret = null;         
        ret  = method.invoke(targetObject, args);      
        returnret; }}Copy the code

Test code:

JDKProxy jdkProxy=new JDKProxy();
UserService userService = (UserService) 
jdkProxy.newProxy(new UserServiceImp());    
userService.addRole("Super Administrator");    
Copy the code

The basic idea behind JDK dynamic proxies is to create a new class from the interface passed in according to defined rules.

CGLIB dynamic proxy

The JDK dynamic proxy requires an interface. CGLIB (Code Generate Library) dynamic proxy does not. It does this by creating a subclass of the promenade class and then modifying the Code using the ASM bytecode Library.

public class CGLibProxy implements MethodInterceptor {    
    private Object targetObject; // Proxy object

    public Object createProxyObject(Object obj) {    
        this.targetObject = obj;    
        Enhancer enhancer = new Enhancer();    
        enhancer.setSuperclass(obj.getClass());    
        enhancer.setCallback(this);    
        Object proxyObj = enhancer.create();    
        return proxyObj;
    }    
    
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {    
        Object obj = null;       
        obj = method.invoke(targetObject, args);    
        returnobj; }}Copy the code

Test code:

CGLibProxy cgLibProxy=new CGLibProxy();
UserService userService = (UserService) 
cgLibProxy.newProxy(new UserServiceImp());    
userService.addRole("Super Administrator");    
Copy the code

ASM is a Java bytecode manipulation framework. It can modify existing classes in binary form or generate classes dynamically. However, ASM creates class bytecode at the assembly instruction level of the underlying JVM, which requires ASM users to have some understanding of the class organization structure and JVM assembly instructions. Bytecode can also be manipulated using the Javassist framework, which is optimized for the interface provided by the developer.

Understand reflection and dynamic proxy, for the later introduction of MyBatis parsing and operation principle is of great help, the next chapter will focus on.

Please scan the qr code below and follow my personal wechat official account ~