Myabtis動態代理實現Mapper
阿新 • • 發佈:2022-05-26
動態代理
public class Main { public static void main(String[] args) { final ProxyMapper mapper = (ProxyMapper) Proxy.newProxyInstance(Main.class.getClassLoader(), new Class[]{ProxyMapper.class}, new InvocationHandler() { @Override public Object invoke(Object o, Method method, Object[] objects) throwsView CodeThrowable { return 1; } }); mapper.select(); } interface ProxyMapper { int select(); } }
代理類內容
final class $Proxy0 extends Proxy implements PorxyMapper { private static Method m1; private static Method m2; privateView Codestatic Method m3; private static Method m0; public $Proxy0(InvocationHandler var1) throws { super(var1); } public final boolean equals(Object var1) throws { try { return (Boolean)super.h.invoke(this, m1, new Object[]{var1}); } catch (RuntimeException | Error var3) {throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final String toString() throws { try { return (String)super.h.invoke(this, m2, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final int select() throws { try { return (Integer)super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final int hashCode() throws { try { return (Integer)super.h.invoke(this, m0, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object")); m2 = Class.forName("java.lang.Object").getMethod("toString"); m3 = Class.forName("com.mochasoft.nonstop.config.Main$PorxyMapper").getMethod("select"); m0 = Class.forName("java.lang.Object").getMethod("hashCode"); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } } }
Mybatis程式碼
public class Main { public static void main(String[] args) { System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true"); HikariDataSource dataSource = new HikariDataSource(); TransactionFactory transactionFactory = new JdbcTransactionFactory(); Environment environment = new Environment("development", transactionFactory, dataSource); Configuration configuration = new Configuration(environment); configuration.addMapper(ProxyMapper.class); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration); final SqlSession sqlSession = sqlSessionFactory.openSession(); final ProxyMapper mapper = sqlSession.getMapper(ProxyMapper.class); } interface ProxyMapper { @Select("select * from dual") int select(); } }View Code
建立Mapper代理類
MapperRegistry.getMapper
public <T> T getMapper(Class<T> type, SqlSession sqlSession) { final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); } try { return mapperProxyFactory.newInstance(sqlSession); } catch (Exception e) { throw new BindingException("Error getting mapper instance. Cause: " + e, e); } }
MapperProxyFactory.newInstance
public T newInstance(SqlSession sqlSession) { final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache); return newInstance(mapperProxy); }
MapperProxy.invoke
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { if (Object.class.equals(method.getDeclaringClass())) { return method.invoke(this, args); } else if (method.isDefault()) { return invokeDefaultMethod(proxy, method, args); } } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } final MapperMethod mapperMethod = cachedMapperMethod(method); return mapperMethod.execute(sqlSession, args); }
記錄Mybatis的Mapper:
一般我們使用JDK動態代理的時候,會對一個介面已有的實現類進行代理,進而會進入一個誤區 => JDK動態代理會有一個介面實現類的入參。