JDK Mybatis explore the dynamic proxy: Explore Proxy.newProxyInstance () generated proxy class parses

Mybatis the Mapper interfaces UserMapper

 1 package com.safin.Mapper;
 2 
 3 import com.safin.Pojo.User;
 4 
 5 import java.util.List;
 6 
 7 public interface UserMapper {
 8     int insertUser(User user);
 9     User getUser(Long id);
10     List<User> findUser(String userName);
11 }

jdk version I use is 12, ProxyGenerator in java.lang.reflect package is a tool to generate a proxy class, which is used to generate runtime proxy class ($ proxy prefixed). Note that one of the properties, which is used to save those switches constructed saveGeneratedFiles proxy class, the default assignment is false, when saveGeneratedFiles is true, that runtime generated proxy class will be preserved in the .class files.

1 /** debugging flag for saving generated class files */
2     private static final boolean saveGeneratedFiles =
3         java.security.AccessController.doPrivileged(
4             new GetBooleanAction(
5                 "jdk.proxy.ProxyGenerator.saveGeneratedFiles")).booleanValue();

In a first test start the main function to add the following code, the switch opens saveGeneratedFiles. jdk12 in " jdk.proxy.ProxyGenerator.saveGeneratedFiles" jdk8 This value is slightly different, this value is in jdk8 "sun.misc.ProxyGenerator.saveGeneratedFiles". Misc talking, his full name should be minimal instruction set computer, a minimum instruction set computer processor architecture, a very small number of basic operations and corresponding operation code.

There jdk8 and Implementation of Proxy jdk12 has undergone great changes, after a time to go research study.

1 System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");

Main function test is as follows:

 1 public static void main(String[] args) throws IOException {
 2         SqlSession sqlSession = null;
 3         System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true"); // 打开保存生成的代理类
 4 
 5         try {
 6             sqlSession = SqlSessionFactoryUtil.openSqlSession();
 7             UserMapper userMapper = (UserMapper)sqlSession.getMapper(UserMapper.class);
 8             User user = null;
 9             user = userMapper.getUser(30L);
10             sqlSession.commit();
11         } catch (Exception var9) {
12             System.err.println(var9.getMessage());
13             sqlSession.rollback();
14         } finally {
15             if (sqlSession != null) {
16                 sqlSession.close();
17             }
18 
19         }
20 
21     }

After running to save a lot of proxy class to find out the proxy class $ proxy, the proxy classes and after-related Mapper decompile IDEA, the code is as follows:

  1 //
  2 // Source code recreated from a .class file by IntelliJ IDEA
  3 // (powered by Fernflower decompiler)
  4 //
  5 
  6 package com.sun.proxy;
  7 
  8 import com.safin.Mapper.UserMapper;
  9 import com.safin.Pojo.User;
 10 import java.lang.reflect.InvocationHandler;
 11 import java.lang.reflect.Method;
 12 import java.lang.reflect.Proxy;
 13 import java.lang.reflect.UndeclaredThrowableException;
 14 import java.util.List;
 15 
 16 public final class $Proxy19 extends Proxy implements UserMapper {
 17     private static Method m1;
 18     private static Method m3;
 19     private static Method m4;
 20     private static Method m5;
 21     private static Method m2;
 22     private static Method m0;
 23    
 24     public $Proxy19(InvocationHandler var1) throws  {
 25         Super (var1); // constructor parameter passed is achieved MapperProxy InvocationHandler interface
 26 is      }
 27  
28      public  Final  Boolean the equals (Object var1) throws   {
 29          the try {
 30              return (Boolean) Super .h.invoke ( the this , M1, new new Object [] {} var1); // invoke method from the InvocationHandler
 31 is          } the catch (a RuntimeException | Error var3) {
 32              the throw var3;
 33 is          } the catch (the Throwable var4) {
 34 is              the throw  new new UndeclaredThrowableException(var4);
 35         }
 36     }
 37 
 38     public final User getUser(Long var1) throws  {
 39         try {
 40             return (User)super.h.invoke(this, m3, new Object[]{var1});
 41         } catch (RuntimeException | Error var3) {
 42             throw var3;
 43         } catch (Throwable var4) {
 44             throw new UndeclaredThrowableException(var4);
 45         }
 46     }
 47 
 48     public final int insertUser(User var1) throws  {
 49         try {
 50             return (Integer)super.h.invoke(this, m4, new Object[]{var1});
 51         } catch (RuntimeException | Error var3) {
 52             throw var3;
 53         } catch (Throwable var4) {
 54             throw new UndeclaredThrowableException(var4);
 55         }
 56     }
 57 
 58     public final List findUser(String var1) throws  {
 59         try {
 60             return (List)super.h.invoke(this, m5, new Object[]{var1});
 61         } catch (RuntimeException | Error var3) {
 62             throw var3;
 63         } catch (Throwable var4) {
 64             throw new UndeclaredThrowableException(var4);
 65         }
 66     }
 67 
 68     public final String toString() throws  {
 69         try {
 70             return (String)super.h.invoke(this, m2, (Object[])null);
 71         } catch (RuntimeException | Error var2) {
 72             throw var2;
 73         } catch (Throwable var3) {
 74             throw new UndeclaredThrowableException(var3);
 75         }
 76     }
 77 
 78     public final int hashCode() throws  {
 79         try {
 80             return (Integer)super.h.invoke(this, m0, (Object[])null);
 81         } catch (RuntimeException | Error var2) {
 82             throw var2;
 83         } catch (Throwable var3) {
 84             throw new UndeclaredThrowableException(var3);
 85         }
 86     }
 87 
 88     static { // 拿到了反射API的Method
 89         try {
 90             m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
 91             m3 = Class.forName("com.safin.Mapper.UserMapper").getMethod("getUser", Class.forName("java.lang.Long"));
 92             m4 = Class.forName("com.safin.Mapper.UserMapper").getMethod("insertUser", Class.forName("com.safin.Pojo.User"));
 93             m5 = Class.forName("com.safin.Mapper.UserMapper").getMethod("findUser", Class.forName("java.lang.String"));
 94             m2 = Class.forName("java.lang.Object").getMethod("toString");
 95             m0 = Class.forName("java.lang.Object").getMethod("hashCode");
 96         } catch (NoSuchMethodException var2) {
 97             throw new NoSuchMethodError(var2.getMessage());
 98         } catch (ClassNotFoundException var3) {
 99             throw new NoClassDefFoundError(var3.getMessage());
100         }
101     }
102 }

You can see the generated proxy class inherits $ Proxy19 Proxy class that implements Mybatis of UserMapper interface method calls invoke InvocationHandler to use MapperMethod to the operation of the sqlSession.

 

 

Guess you like

Origin www.cnblogs.com/magic-sea/p/11229237.html