如果一个类的某一方法我们需要修改其行为, 如数据库连接池中Connection.close()方法, 并不是真正的去关闭连接, 而只是把这个连接放入连接池里, 所以我们需要拦截这个方法的原来行为, 更改为只是放入连接池. 可以简单的继承java.sql.Connection, 然后实现所有方法, 但只更改close()的行为. 这样做很容易理解, 但是如果一个类的方法太多, 做起来工作量可能会很大.
另一种方法就是使用动态代理类来实现: Proxy, InvocationHandler.
import java.util.*;
import java.lang.reflect.*;
public class Test01 {
public static void main(String[] args) {
MyInvocationHandler mih = new MyInvocationHandler();
MyClass mc = new MyClass();
// 当调用mi的方法时, 如果是要特殊处理的就特殊处理, 否则就调用他对应的那个对象(mc)的方法.
MyInterface mi = mih.bind(mc);
mi.fight();
System.out.println(mi.toString());
}
}
interface MyInterface {
void fight();
}
class MyClass implements MyInterface {
public void fight() {
System.out.println("Orz, fighting.....");
}
@Override
public String toString() {
return "Hello";
}
}
class MyInvocationHandler implements InvocationHandler {
MyClass mc;
MyInterface mi;
public MyInterface bind(MyClass mc) {
this.mc = mc;
this.mi = (MyInterface) Proxy.newProxyInstance(MyInterface.class
.getClassLoader(), new Class[] { MyInterface.class }, this);
return mi;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 当调用mi(即proxy)的方法时, 如果是要特殊处理的就特殊处理, 否则就调用他对应的那个对象(mc)的方法.
if ("fight".equals(method.getName())) {
System.out.println("XXXXXXXXXXXXXXXX");
return null;
} else {
return method.invoke(mc, args);
}
}
}