为什么要使用动态代理?

    xiaoxiao2021-12-14  19

    为什么要使用动态代理?也就是说它解决了什么问题。 假如现在有这样的需求 需求1-日志:在程序执行期间追踪正在发生的活动 需求2-验证:希望计算器只能处理正数的运算

    比如:一个加减乘除 运算的类 可能会这么写代码

    这样的代码有两个致命的问题。

    代码混乱:越来越多的非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀. 每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点. 比如:每新添加了方法,还得继续写日志和验证代码分散: 以日志需求为例, 只是为了满足这个单一需求, 就不得不在多个模块(方法)里多次重复相同的日志代码. 如果日志需求发生变化, 必须修改所有模块. 比如:现在此类的方法里都显示方法名,那么每个方法都得一个一个改

    那么现在加入动态代理能解决上述问题

    那么上代码 首先写个接口,因为后面代理类要用接口得到实现类的方法 public interface ArithmeticCalculator {

    int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j);

    }

    **然后写接口的实现类** public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int i, int j) { int result = i + j; return result; } @Override public int sub(int i, int j) { int result = i - j; return result; } @Override public int mul(int i, int j) { int result = i * j; return result; } @Override public int div(int i, int j) { int result = i / j; return result; } } **然后写实现动态代理的类** import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; public class ArithmeticCalculatorLoggingProxy { //要代理的对象 private ArithmeticCalculator target; public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) { super(); this.target = target; } //返回代理对象 public ArithmeticCalculator getLoggingProxy(){ ArithmeticCalculator proxy = null; ClassLoader loader = target.getClass().getClassLoader(); Class [] interfaces = new Class[]{ArithmeticCalculator.class};//这个class是代理对象实现的接口 InvocationHandler h = new InvocationHandler() { /** * proxy: 代理对象。 一般不使用该对象 * method: 正在被调用的方法 * args: 调用方法传入的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); //打印日志 System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args)); //调用目标方法 Object result = null; try { //前置通知 result = method.invoke(target, args); //返回通知, 可以访问到方法的返回值 } catch (NullPointerException e) { e.printStackTrace(); //异常通知, 可以访问到方法出现的异常 } //后置通知. 因为方法可以能会出异常, 所以访问不到方法的返回值 //打印日志 System.out.println("[after] The method ends with " + result); return result; } }; /** * loader: 代理对象使用的类加载器。 * interfaces: 指定代理对象的类型. 即代理代理对象中可以有哪些方法. * h: 当具体调用代理对象的方法时, 应该如何进行响应, 实际上就是调用 InvocationHandler 的 invoke 方法 */ proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h); return proxy; } } 最后调用main方法执行 public static void main(String[] args) { ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl(); arithmeticCalculator = ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy(); int result = arithmeticCalculator.add(11, 12); System.out.println("result:" + result); result = arithmeticCalculator.div(21, 3); System.out.println("result:" + result);

    } “` 动态代理执行结果

    转载请注明原文地址: https://ju.6miu.com/read-962926.html

    最新回复(0)