[1] 声明计算器接口
public interface Calculator {
void add(int a, int b);
void sub(int a, int b);
void mul(int a, int b);
void div(int a, int b);
}
[2] 创建计算器接口实现类
public class CalculatorImpl implements Calculator {
@Override
public void add(int a, int b) {
System.out.println(“(a + b) = ” + (a + b));
}
@Override
public void sub(int a, int b) {
System.out.println(“(a – b) = ” + (a – b));
}
@Override
public void mul(int a, int b) {
System.out.println(“(a × b) = ” + (a * b));
}
@Override
public void div(int a, int b) {
System.out.println(“(a ÷ b) = ” + (a / b));
}
}
局部来看确实实现了代理模式的要求,但是所有代码都是写死的,日志这样的通用功能的代码无法重用,没有任何的灵活性。
public class StaticProxyCalculator implements Calculator {
private Calculator calculator;
public StaticProxyCalculator(Calculator calculator) {
this.calculator = calculator;
}
@Override
public void add(int a, int b) {
System.out.println(“[debug][static proxy]add method begin”);
this.calculator.add(a, b);
System.out.println(“[debug][static proxy]add method end”);
}
@Override
public void sub(int a, int b) {
System.out.println(“[debug][static proxy]sub method begin”);
this.calculator.sub(a, b);
System.out.println(“[debug][static proxy]sub method end”);
}
@Override
public void mul(int a, int b) {
System.out.println(“[debug][static proxy]mul method begin”);
this.calculator.mul(a, b);
System.out.println(“[debug][static proxy]mul method end”);
}
@Override
public void div(int a, int b) {
System.out.println(“[debug][static proxy]div method begin”);
this.calculator.div(a, b);
System.out.println(“[debug][static proxy]div method end”);
}
}
/**
* 专门抽取日志打印功能的动态代理类
*/
public class DynamicLogProxy {
// 被代理的目标对象
private Object target;
// 通过构造器接收被代理的目标对象
public DynamicLogProxy(Object target) {
this.target = target;
}
public Object getProxy() {
return Proxy.newProxyInstance(
// 目标对象的类加载器
this.target.getClass().getClassLoader(),
// 目标对象实现的所有接口(既然代理对象是为target对象做代理,那么就应该和target对象一样实现target对象的所有接口
this.target.getClass().getInterfaces(),
// InvocationHandler对象
(Object proxy, Method method, Object[] args)->{
// 获取被代理的目标方法的方法名
String methodName = method.getName();
Object returnValue = null;
try {
// 方法开始执行前位置
System.out.println(“[Log]Method ” + methodName + ” begin.”);
// 通过反射调用目标方法
returnValue = method.invoke(target, args);
// 方法正常结束位置(寿终正寝)
System.out.println(“[Log]Method ” + methodName + ” ended successfully.”);
} catch (Exception e) {
String exceptionName = e.getClass().getName();
while (e.getCause() != null) {
exceptionName = e.getCause().getClass().getName();
e = (Exception) e.getCause();
}
// 方法异常结束位置(死于非命)
System.out.println(“[Log]Method ” + methodName + ” ended with exception: “+ exceptionName +”.”);
} finally {
// 方法最终结束位置(盖棺定论)
System.out.println(“[Log]Method ” + methodName + ” finally ended.”);
}
return returnValue;
});
}
}
junit测试:
@Test
public void testDynamicLogProxy() {
// 1.创建被代理对象
Calculator target = new CalculatorImpl();
// 2.创建代理对象
DynamicLogProxy proxy = new DynamicLogProxy(target);
Calculator calculator = (Calculator) proxy.getProxy();
// 3.通过代理对象调用业务方法
calculator.add(3, 5);
calculator.sub(6, 2);
calculator.mul(4, 7);
calculator.div(3, 0);
}
想要了解跟多关于java培训课程内容欢迎关注尚硅谷java培训,尚硅谷除了这些技术文章外还有免费的高质量java培训课程视频供广大学员下载学习。