Java中动态代理的使用
什么是代理?
代理就是代替目标对象去完成某些事情。有一个很火的明星,开通了一个抖音账号,这个账号非常活跃,回复粉丝、到处点赞之类的,但可能并不是真的由本人在维护的。
而是在背后有一个其他人 or 团队来运营,我们就可以称他们为代理人,因为他们发表的内容就代表了明星本人的意思。
为什么需要代理?
实现AOP 面向切面编程
将业务核心代码与辅助业务代码解耦。
代码实现
1.定义一个接口
package proxy;
public interface Calculator {
public int add(int i,int j);
}
- 创建一个该接口的实现类
package proxy;
public class MyCalculator implements Calculator {
@Override
public int add(int i,int j) {
return i+j;
}
}
- 创建一个代理对象生成类。
该类的作用就是为目标对象,生成它的代理对象。
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/**
* 为MyCalculator这个类创建一个代理对象
*/
public class MyCalculatorProxy {
public static Calculator getProxy(Calculator calculator){
ClassLoader loader =calculator.getClass().getClassLoader();
Class<?>[] interfaces = calculator.getClass().getInterfaces();
// 方法执行器,这个东西帮我们目标对象执行目标方法。
InvocationHandler h = new InvocationHandler() {
@Override
/**
* @param proxy:代理对象,这个给jdk使用,程序员不要动这个对象
* @param method:当前要执行的目标方法
* @param args: 外界调用时传入的参数值
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 利用反射来执行方法
Object result = method.invoke(calculator,args);
// 要把执行结果返回出去,外界调用时才能拿到返回值。
return result;
}
};
// Proxy为目标对象创建代理对象
// 此处使用lambda表达式简写。
Object myProxy = Proxy.newProxyInstance(loader,interfaces,(Object proxy, Method method, Object[] args)->{
// 可在此处添加额外的代码,完成一些辅助功能,比如日志收集……
System.out.println("动态代理执行方法");
Object result = method.invoke(calculator,args);
return result;
});
return (Calculator) myProxy;
}
}
与JavaScript中的代理对比
JavaScript中的代理功能更为强大,也可以实现上述功能。除此之外该可以给JavaScript提供类似getter()、 setter()这样的功能,让JavaScript在某些时候能更像Java。
不错的参考文献
https://www.jianshu.com/p/4dcc74b63f1c