最近了解了一下JDK动态代理。
总结了一下,什么叫代理,就是某个对象实例的方法执行,交给别人去执行,别人代理执行的时候,还可以自己加入一些动作。
写动态代理主要有如下几个步骤:
1)被代理的类A需要实现某些接口
2)定义一个handler ,需要实现InvocationHandler的接口,同时实现invoke的方法。这个invoke方法就是代理对象执行被代理对象方法时进入的方法。
先介绍一下这个方法的几个参数:public Object invoke(Object object, Method method, Object[] args)
object:指代我们所代理的对象(这个对象在测试的过程没有用过,具体后面会继续补充)
method:指代我们所代理的对象方法的Method对象
args:指代上面方法的参数
根据代理的目的,其实是要在真实执行方法的前后添加某些执行逻辑。
所以代理对象首先在invoke里需要通过反射来执行被代理对象的Method方法,即method.invoke(realObject, args),注意这个realObject是被代理的对象实例
需要传参进去。然后在此方法前后加入要添加的操作。
3)实现一个被代理类A的实例,实现一个handler实例,并且将A实例传进去(此实例就是在invoke方法里的realObject对象)。
接着通过Proxy.newProxyInstance方法来创建一个代理对象,通过代理对象执行被代理对象的某个方法,之前我们在handler里写的invoke方法就会被执行。
这里介绍一下创建代理对象的方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
loader:定义由哪个ClassLoader来加载生成的代理对象
interface:表示我们要代理的对象实现了一些什么接口。
h:具体的handler对象,表示代理对象在执行被代理对象方法的时候,会关联到哪个具体的handler上去。
然后提供一些具体的代码实现:
被代理类的接口:
public interface Action {
public void run();
public void eat();
}
被代理类:
public class Person implements Action{
@Override
public void run() {
System.out.println("Person: I am running.");
}
@Override
public void eat() {
System.out.println("Person: I am eating.");
}
}
public class ProxySubject implements InvocationHandler{
private Object target;
public ProxySubject(Object obj){
this.target = obj;
}
@Override
public Object invoke(Object o, Method method, Object[] args)
throws Throwable {
System.out.println("Proxy: before Person perform action....");
Object result = method.invoke(target, args);
System.out.println("Proxy: after Persion perform action....");
return result;
}
}
public class TestMain {
public static void main(String[] args){
//真实对象
Person person = new Person();
//handler
ProxySubject handler = new ProxySubject(person);
//代理对象
Action proxyObject = (Action) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), handler);
proxyObject.run();
proxyObject.eat();
}
}