概述
使用动态代理使得在不影响打印日志的类的情况下进行日志打印,也就解耦业务逻辑和日志打印
代码
代码执行流程:Proxy->获取代理ProxyCalculator.getProxy,代理执行对应的方法,并打印日志
测试类ProxyTest
1 2 3 4 5 6 7 8 9 10 11 12
| import xyz.lyhcc.calculate.Calculator; import xyz.lyhcc.calculate.MathCalculator; import xyz.lyhcc.proxy.ProxyCalculator;
public class ProxyTest { @Test public void test() { Calculator proxy = (Calculator) ProxyCalculator.getProxy(new MathCalculator()); proxy.add(1,2); proxy.div(10, 2); } }
|
代理获取类ProxyCalculator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
import xyz.lyhcc.calculate.Calculator; import xyz.lyhcc.logger.LoggerUtils;
public class ProxyCalculator { public static Calculator getProxy(Calculator calculator) { ClassLoader loader = calculator.getClass().getClassLoader(); Class<?>[] interfaces = calculator.getClass().getInterfaces(); InvocationHandler h = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { LoggerUtils.logStart(method, args); result = method.invoke(calculator, args); LoggerUtils.logFinished(method, result); } catch (Exception e) { LoggerUtils.logError(method, e); } return result; } }; Object proxy = Proxy.newProxyInstance(loader, interfaces, h); return (Calculator) proxy; } }
|
日志类 LoggerUtils
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.lang.reflect.Method; import java.util.Arrays;
public class LoggerUtils { public static void logStart(Method method, Object... args) { System.out.println("[" + method.getName() + " is running..] args=" + Arrays.asList(args)); } public static void logFinished(Method method, Object result) { System.out.println("[" + method.getName() + " is Finished...] result=" +result); } public static void logError(Method method, Exception e) { System.out.println("[" + method.getName() + " has errors] error is " + e.getCause()); } }
|
计算器类和接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public interface Calculator { public int add(int x, int y); public int sub(int x, int y); public int multi(int x, int y); public int div(int x, int y); }
public class MathCalculator implements Calculator{
@Override public int add(int x, int y) { return x + y; }
@Override public int sub(int x, int y) { return x - y; }
@Override public int multi(int x, int y) { return x * y; }
@Override public int div(int x, int y) { return x / y; }
}
|
动态代理的问题
- 当没有实现任何接口时无法使用动态代理,代理对象和被代理对唯一能产生的关联就是实现了同一接口
- 实现起来困难