代理模式
1、理论介绍
① 概念
代理模式是二十三种设计模式中的一种,属于结构型模式。
它的作用就是通过提供一个代理类,让我们再调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来。调用目标方法时先调用代理对象的方法,减少对目标方法的调用和打扰。
② 相关术语
- 代理:将非核心逻辑剥离出来以后,封装这些非核心逻辑的类、对象、方法。
- 目标:被代理“套用”了非核心逻辑代码的类、对象、方法。
2、代码实现
① 情景设定
[1]创建计算器接口
1 2 3 4 5 6 7 8 9 10 11
| public interface ICalculator {
int add(int i, int j);
int sub(int i, int j);
int mul(int i, int j);
int div(int i, int j);
}
|
[2]创建计算器接口的实现类
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
| public class CalculatorImpl implements ICalculator { @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; } }
|
② 使用动态代理
效果:假设我们针对日志功能进行代理,那么这个类专门负责给其他类增加日志的功能,不管目标类是什么,使用这个代理类之后都能够增加日志功能。
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| public class LogDynamicProxyFactory {
private Object target;
public LogDynamicProxyFactory(Object target) { this.target = target; }
public Object getProxyObject() {
ClassLoader classLoader = this.target.getClass().getClassLoader();
Class<?>[] interfaces = this.target.getClass().getInterfaces();
InvocationHandler invocationHandler = (
Object proxy,
Method method,
Object[] args) -> {
Object targetMethodReturnValue = null; String methodName = method.getName(); List<Object> argList = Arrays.asList(args);
try { System.out.println("[代理]" + methodName + "方法开始执行,参数列表是:" + argList);
method.setAccessible(true);
targetMethodReturnValue = method.invoke(target, args);
System.out.println("[代理]" + methodName + "方法成功结束,执行结果是:" + targetMethodReturnValue); } catch (Exception e) { e.printStackTrace();
System.out.println("[代理]" + methodName + "方法异常结束,抛出异常是:" + e);
} finally {
System.out.println("[代理]" + methodName + "方法最终结束");
}
return targetMethodReturnValue; };
return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler); } }
|
⑤ 测试方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Test public void testDynamicProxy() { ICalculator target = new CalculatorImpl();
LogDynamicProxyFactory factory = new LogDynamicProxyFactory(target);
ICalculator proxyObject = (ICalculator) factory.getProxyObject();
int addResult = proxyObject.add(6, 3); System.out.println("[测试]addResult = " + addResult);
int subReult = proxyObject.sub(6, 3); System.out.println("[测试]subReult = " + subReult);
int mulResult = proxyObject.mul(6, 3); System.out.println("[测试]mulResult = " + mulResult);
int divResult = proxyObject.div(6, 0); System.out.println("[测试]divResult = " + divResult); }
|