动态代理属于Java反射的一种。
当我们得到一个对象,想动态的为其一些方法每次被调用前后追加一些操作时,我们将会用到java动态代理。
下边上代码:
首先定义一个接口:
package com.liuyx;
public interface Itf {
public abstract void printMe();
public abstract void printSth(String me);
}
接着是它的实现:
package com.liuyx;
public class Cls implements Itf {
@Override
public void printMe() {
System.out.println("I'm Cls!");
}
@Override
public void printSth(String str) {
System.out.println(str);
}
}
我们的目的就是通过动态代理技术,在Cls这个类的对象的两个方法执行前后,加上一些打印操作。
现在我们实现一个InvocationHandler,把我们想要通过代理者给被代理者追加的操作都写在invoke方法里面:
package com.liuyx;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class StandardInvocation implements InvocationHandler {
private Object obj;
StandardInvocation(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before method excute!");
Object result = method.invoke(obj, args);
System.out.println("after method excute!");
return result;
}
}
首先、这里面有一个obj,这个obj是必须的,我们既然要做代理,我们必须知道我们是给谁做代理,这里的obj就是被代理者。动态代理说到底也是代理,代理模式里就要求有一个被代理者。
然后是invoke的三个参数、第一个参数就是代理者,如果你想对代理者做一些操作可以使用这个参数;第二个就是被执行的方法,第三个是执行该方法所需的参数。
当你执行代理者的某个方法的时候,最后跑的都是invoke方法。
pxy就是c的代理者。
最后来一个稍微改进的写法:
package com.liuyx;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class InvocationHandlerTest implements InvocationHandler {
private Object target;
Object bind(Object i) {
target = i;
Object warpedItf;
warpedItf = Proxy.newProxyInstance(target.getClass().getClassLoader(), i.getClass().getInterfaces(), this);
return warpedItf;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before method excute!");
method.invoke(target, args);
System.out.println("after method excute!");
return null;
}
public static void main(String[] args) {
Cls c = new Cls();
InvocationHandlerTest pxy = new InvocationHandlerTest();
Itf itf = (Itf)pxy.bind(c);
itf.printSth("Hello");
}
}