1. 程式人生 > 實用技巧 >動態代理,沒有被代理物件

動態代理,沒有被代理物件

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直接生成代理物件,沒有被代理物件,因為連被代理實現類都沒有