标签:对象 system invoke final 代理模式 a* 执行器 输出 oca
对于一个类的方法
public class Calculator {
public void add(int i,int j){
System.out.println("add方法调用,参数为"+i+","+j);
System.out.println(i + j);
System.out.println("add方法结束,结果为"+(i+j));
}
public void sub(int i, int j){
System.out.println(i - j);
}
}
我们想打印日志信息,或者保存日志信息。我们需要在方法执行的前后加上打印输出或者日志记录的代码,如上的add方法中
但是,当我们如果某天我们不想要记录日志信息,我们需要手动删除日志语句。
public interface Calculator {
public int add(int a, int b);
public int sub(int a, int b);
public int mul(int a, int b);
public int div(int a, int b);
}
public class MyMathCalculator implements Calculator {
public int add(int a, int b) { return a+b; }
public int sub(int a, int b) { return a-b; }
public int mul(int a, int b) { return a*b; }
public int div(int a, int b) { return a/b; }
}
主要是使用java的Proxy.newProxyInstance()来创建动态代理对象。
主要用到了反射的知识奥,8会的建议去看一看发射。
public class CalculatorProxy{
public static Calculator getProxy(final Calculator calculator){
ClassLoader classLoader = calculator.getClass().getClassLoader();
Class<?>[] classes = calculator.getClass().getInterfaces();
//方法执行器。帮我们目标对象执行目标方法-----匿名接口对象
InvocationHandler invocationHandler = new InvocationHandler() {
/**
* @param proxy 代理对象;给jdk使用,任何时候都不要动这个对象
* @param method 当前将要执行的目标对象的方法
* @param args 这个方法调用时外界传,入的参数值
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//利用反射执行目标方法
//目标执行后的返回值
System.out.println("动态代理执行");
Object result = method.invoke(calculator, args);
//返回值必须返回出去外界才能拿到真正执行后的返回值
return result;
}
};
//Proxy为目标对象创建代理对象
Object o = Proxy.newProxyInstance(classLoader, classes, invocationHandler);
return (Calculator) o;
}
}
public static void main(String[] args) {
//普通调用
Calculator calculator = new CalculatorImpl();
calculator.add(2,3);
System.out.println(calculator.getClass());
//代理调用
Calculator proxy = CalculatorProxy.getProxy(calculator);
proxy.add(1,2);
System.out.println(proxy.getClass());
}
疑惑:
class com.sun.proxy.$Proxy0
而我们的对象是
class com.xj.day0904Proxy.CalculatorImpl
如果没有接口存在,可以看出两个类型是没有任何关系的
但是有了这个接口后,两个类都实现了同一个接口,此时,代理类也就具有了add,sub等等的方法;
之后代理类调用add方法后,就会去执行被代理对象的各种方法,并且在执行前后进行日志等操作
标签:对象 system invoke final 代理模式 a* 执行器 输出 oca
原文地址:https://www.cnblogs.com/flower1360/p/13616472.html