您的位置:首页 > 其它

关于动态代理的一点疑问

2017-08-29 00:37 302 查看
看到动态代理时,有一个疑问:既然InvocationHandler实现类中已经在构造参数中获取到了Connection对象(Connection是接口,拿到的是实现该接口的对象),为什么还要使用method.invoke方法,而不直接使用对象调用方法?后来看到实际应用中的情况,我想时出于一下亮点考虑:

1、Connection中有多个方法,使用invoke时,只要传入Connection的Method对象就可以调用对应的方法,而代码完全不用修改,提高了代码重用性。

2、在Connection接口的实现类中,可能扩展了Connection接口;定义了一些Connection中没有的方法,此时使用invoke仍然可以调用到该方法。而使用connection调用则调用不到。因为在invoke中做了类型转换,

ps:可参考以下文章

http://blog.csdn.net/hubiao_0618/article/details/38409303

http://blog.csdn.net/hubiao_0618/article/details/38523281

package org.apache.ibatis.logging.jdbc;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;

import org.apache.ibatis.logging.Log;
import org.apache.ibatis.reflection.ExceptionUtil;

public final class ConnectionLogger extends BaseJdbcLogger implements InvocationHandler {

private Connection connection;

private ConnectionLogger(Connection conn, Log statementLog, int queryStack) {
super(statementLog, queryStack);
this.connection = conn;
}

@Override
public Object invoke(Object proxy, Method method, Object[] params)
throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, params);
}
if ("prepareStatement".equals(method.getName())) {
if (isDebugEnabled()) {
debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
return stmt;
} else if ("prepareCall".equals(method.getName())) {
if (isDebugEnabled()) {
debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
return stmt;
} else if ("createStatement".equals(method.getName())) {
Statement stmt = (Statement) method.invoke(connection, params);
stmt = StatementLogger.newInstance(stmt, statementLog, queryStack);
return stmt;
} else {
return method.invoke(connection, params);
}
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息