動態代理,沒有被代理物件
阿新 • • 發佈:2020-08-29
1 在mybatis Guice 事務原始碼解析中,可以發現SqlSessionManager中的sqlSessionProxy使用SqlSession構建的代理
private SqlSessionManager(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; this.sqlSessionProxy = (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionManager.SqlSessionInterceptor()); }
this.sqlSessionProxy = (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionManager.SqlSessionInterceptor());
******************************
private class SqlSessionInterceptor implements InvocationHandler {
public SqlSessionInterceptor() {}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
SqlSession sqlSession = (SqlSession)SqlSessionManager.this.localSqlSession.get();
if(sqlSession != null) {
try {
return method.invoke(sqlSession, args);
} catch (Throwable var19) {throw ExceptionUtil.unwrapThrowable(var19);
}
} else {
SqlSession autoSqlSession = SqlSessionManager.this.openSession();
Throwable var6 = null;
Object var8;
try {
try {
Object t = method.invoke(autoSqlSession, args);
autoSqlSession.commit();
var8 = t;
} catch (Throwable var20) {
autoSqlSession.rollback();
throw ExceptionUtil.unwrapThrowable(var20);
}
} catch (Throwable var21) {
var6 = var21;
throw var21;
} finally {
if(autoSqlSession != null) {
if(var6 != null) {
try {
autoSqlSession.close();
} catch (Throwable var18) {
var6.addSuppressed(var18);
}
} else {
autoSqlSession.close();
}
}
}
return var8;
}
}
}
可以看到沒有維護被代理的target物件,用的時候即時生成被代理的DefaultSqlSession物件
public class ProxyFactory implements InvocationHandler { //維護一個目標物件 private Object target; public ProxyFactory(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("開始事務jdk"); Object returnValue = method.invoke(target, args); System.out.println("提交事務jdk"); return returnValue; } //給目標物件生成代理物件 public Object getProxyInstance(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } } public class ProxyFactoryNonTarget implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("開始事務jdk"); Object returnValue = method.invoke(new UserDao(), args); System.out.println("提交事務jdk"); return returnValue; } //給目標物件生成代理物件 public Object getProxyInstance(){ return Proxy.newProxyInstance(ProxyFactoryNonTarget.class.getClassLoader(), new Class[]{IUserDao.class}, this); } }
下面的每次invoke都生成新物件
2 mybatis本身就是根據interface直接生成代理物件,沒有被代理物件,因為連被代理實現類都沒有