关键的类:java.lang.reflect.Proxy,java.lang.reflect.InvocationHandler
关键的方法:
Proxy类的
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) throws IllegalArgumentException
参数说明:
loader:用来加载被代理类的classloader
interfaces: 被代理类实现的接口
h:当被代理类调用实现的接口的某个方法时,由此handler来决定怎么做
通过上面的参数分析,可以看出要让一个class被代理,需要几个步骤:
1. 定义一个或多个interface,被代理类实现这些interface
2. 定一个handler,此handler必须实现InvocationHandler接口
InvocationHandler接口只有一个方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
参数说明:
proxy: 被代理类的instance
method: 被代理类调用的方法,属于上面某个interface的
args: 此方法的参数
从上可以看出,此方法是利用发射来达到调用某个方法的目的,为什么不直接调呢?这样的目的是可以在真正调用此方法前后做一些其他的事情。
具体的例子:
1. 定义一个或多个interface,被代理类实现这些interface
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface AnInterface {
public void doSth();
}
interface AnotherInterface {
public void anotherdo();
}
class AClass implements AnInterface,AnotherInterface {
public void doSth(){
System.out.println("inside AClass.doSth");
}
public void anotherdo() {
System.out.println("inside AClass.anotherdo");
}
}
2. 定一个handler,此handler必须实现InvocationHandler接口
class SimpleInvocationHandler implements InvocationHandler {
private Object realObject;
public SimpleInvocationHandler(Object realObject){
this.realObject = realObject;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
System.out.println("Before calling: "+method.getName());
result = method.invoke(realObject, args);
System.out.println("After calling: "+method.getName());
System.out.println(proxy.getClass().getName());
return result;
}
}
3. 查看效果
public class ProxyTest {
public static void main(String[] args) {
AnInterface realSubject = new AClass();
Class[] clazs = realSubject.getClass().getInterfaces();
for(Class c : clazs) {
System.out.println(c.getName());
AnInterface proxy = (AnInterface)Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
// realSubject.getClass().getInterfaces(),
new Class[]{AnInterface.class},
new SimpleInvocationHandler(realSubject));
proxy.doSth();
System.out.println(Proxy.isProxyClass(proxy.getClass()));
System.out.println(proxy instanceof AnInterface);
if(proxy instanceof AnotherInterface){
AnotherInterface ai = (AnotherInterface)proxy;
ai.anotherdo();
}
}
}
}
注:生成的代理类都是以$Proxy开头的,尽管自己新建一个类的时候也可以以$Proxy开头,但是不建议这么做