介绍动态代理的使用。
使用场景:
业务需要加上“开始...结束...”类型日志,如果在每个业务中都加上日志代码会很繁琐,如果使用动态代理就方便多了。
详细:
ArithmeticCalculator.java:
package com.shuoeasy.test; /** * 定义计算器接口 * */ public interface ArithmeticCalculator { double add(double num1, double num2); double sub(double num1, double num2); double mul(double num1, double num2); double div(double num1, double num2); }
ArithmeticCalculatorImpl.java
package com.shuoeasy.test; /** * 业务类不加日志,使用代理方式实现日志 * */ public class ArithmeticCalculatorImpl implements ArithmeticCalculator{ public double add(double num1, double num2) { double result = num1 + num2; return result; } public double sub(double num1, double num2) { double result = num1 - num2; return result; } public double mul(double num1, double num2) { double result = num1 * num2; return result; } public double div(double num1, double num2) { double result = num1 / num2; return result; } }
ArithmeticCalculatorLoggingProxy.java
package com.shuoeasy.test; import java.lang.reflect.Method; import java.util.Arrays; import org.springframework.cglib.proxy.InvocationHandler; import org.springframework.cglib.proxy.Proxy; /** * 动态代理 */ public class ArithmeticCalculatorLoggingProxy { private ArithmeticCalculator target; public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) { this.target = target; } public ArithmeticCalculator getLogingProxy(){ ArithmeticCalculator proxy = null; // 代理对象由哪一个类加载器负责加载 ClassLoader loader = target.getClass().getClassLoader(); // 代理对象的类型,既其中有哪些方法 Class[] interfaces = new Class[]{ArithmeticCalculator.class}; // 当调用带了对象其中的方法是,该执行的代码 InvocationHandler invocationHandler = new InvocationHandler() { /** * proxy:正在返回的代理对象,一般情况下咋invoke方法中都不适用该对象。 * method:正在被调用的方法。 * args:调用方法是传入的参数。 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); // 日志 System.out.println("The method " + methodName + " begin with " + Arrays.asList(args)); // 执行方法 Object result = method.invoke(target, args); // 日志 System.out.println("The method " + methodName + " end with " + result); return result; } }; proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, invocationHandler); return proxy; } }
Main.java:
package com.shuoeasy.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { // 使用动态代理方式加日志 ArithmeticCalculator target = new ArithmeticCalculatorImpl(); ArithmeticCalculator proxy = new ArithmeticCalculatorLoggingProxy(target).getLogingProxy(); System.out.println("结果" + proxy.add(2, 3) + "\n"); System.out.println("结果" + proxy.sub(2, 3) + "\n"); System.out.println("结果" + proxy.mul(2, 3) + "\n"); System.out.println("结果" + proxy.div(2, 3) + "\n"); } }
输出:
The method add begin with [2.0, 3.0]
The method add end with 5.0
结果5.0
The method sub begin with [2.0, 3.0]
The method sub end with -1.0
结果-1.0
The method mul begin with [2.0, 3.0]
The method mul end with 6.0
结果6.0
The method div begin with [2.0, 3.0]
The method div end with 0.6666666666666666
结果0.6666666666666666