简介
最近接触了java的动态代理的,其实现有多种,这篇只记录一下jdk自带的Proxy,它只对接口有效。
生成代理对象
写了个工具类,方便直接生成动态代理对象,直接InterfaceProxy.createProxy(obj, function)即可得到代理对象,第2个参数function是回调函数,可在被代理对象的方法执行时加一些自己的操作。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 接口动态代理
**/
public class InterfaceProxy {
public interface CallBackFunction {
/**
* 被代理对象方法执行时的回调
* @param proxy 被代理对象
* @param method 执行的方法
* @param args 参数
*/
Object call(Object proxy, Method method, Object[] args);
}
static class ProxyHandler implements InvocationHandler {
private final Object proxyObj;
private final CallBackFunction callBackFunction;
ProxyHandler(Object obj, CallBackFunction function) {
this.proxyObj = obj;
this.callBackFunction = function;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (null != this.callBackFunction) {
return callBackFunction.call(this.proxyObj, method, args);
}
return method.invoke(this.proxyObj, args);
}
}
public static Object createProxy(Object proxied, CallBackFunction function) {
return Proxy.newProxyInstance(proxied.getClass().getClassLoader(),
proxied.getClass().getInterfaces(),
new ProxyHandler(proxied, function));
}
}
测试
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class TestCode {
interface Singer {
void sing();
}
interface Actor {
void perform();
}
static class People implements Singer, Actor {
@Override
public void sing() {
System.out.println("Singer: sing a song");
}
@Override
public void perform() {
System.out.println("Actor: make a film");
}
}
public static void main(String[] args) {
People people = new People();
people.sing();
people.perform();
System.out.println("----------- 分割线 ----------------");
//创建动态代理对象
Object proxiedObj = InterfaceProxy.createProxy(people, new InterfaceProxy.CallBackFunction() {
@Override
public Object call(Object proxy, Method method, Object[] args) {
System.out.println("----------- 代理方法执行前 ----------------");
Object result = null;
try {
result = method.invoke(proxy, args);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("----------- 代理方法执行后 ----------------");
return result;
}
});
System.out.println("动态代理对象实现的接口:" + Arrays.toString(proxiedObj.getClass().getInterfaces()));
System.out.println("动态代理对象是否继承原对象:" + (proxiedObj instanceof People));
((Singer) proxiedObj).sing();
((Actor) proxiedObj).perform();
}
}
输出结果
Singer: sing a song
Actor: make a film
----------- 分割线 ----------------
动态代理对象实现的接口:[interface TestCode$Singer, interface TestCode$Actor]
动态代理对象是否继承原对象:false
----------- 代理方法执行前 ----------------
Singer: sing a song
----------- 代理方法执行后 ----------------
----------- 代理方法执行前 ----------------
Actor: make a film
----------- 代理方法执行后 ----------------