为了解决原始实现中存在的问题,下面考虑使用动态代理来实现。
代理设计模式的原理
使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
类图
实现
package xyz.huning.spring4.aop.calculator;
import org.springframework.stereotype.Component;
@Component
public class PureCalculator implements ICalculator {
@Override
public double add(double x, double y) {
System.out.println("execute method add ...");
return x + y;
}
@Override
public double sub(double x, double y) {
System.out.println("execute method sub ...");
return x - y;
}
@Override
public double mul(double x, double y) {
System.out.println("execute method mul ...");
return x * y;
}
@Override
public double div(double x, double y) {
System.out.println("execute method div ...");
return x / y;
}
}
package xyz.huning.spring4.aop.calculator.proxyimpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import xyz.huning.spring4.aop.calculator.ICalculator;
public class CalculatorLogProxy {
private ICalculator target;
public CalculatorLogProxy(ICalculator target)
{
this.target = target;
}
public ICalculator getProxy()
{
ClassLoader classLoader = target.getClass().getClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
/**
* proxy: 正在返回/执行的代码,一般不在invoke方法中使用
* method: 正在执行的方法
* args: 正在执行方法的参数
*
*/
InvocationHandler handler = new InvocationHandler()
{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before: " + "[x=" + args[0] + ", y=" + args[1] + "]");
Object result = method.invoke(target, args);
System.out.println("after: " + "[x=" + args[0] + ", y=" + args[1] + "]");
return result;
}
};
return (ICalculator)Proxy.newProxyInstance(classLoader, interfaces, handler);
}
}
package xyz.huning.spring4.aop.calculator.proxyimpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import xyz.huning.spring4.aop.calculator.ICalculator;
public class CalculatorValidateProxy {
private ICalculator target;
public CalculatorValidateProxy(ICalculator target)
{
this.target = target;
}
public ICalculator getProxy()
{
ClassLoader classLoader = target.getClass().getClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
InvocationHandler handler = new InvocationHandler()
{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
validate(args);
Object result = method.invoke(target, args);
return result;
}
};
return (ICalculator)Proxy.newProxyInstance(classLoader, interfaces, handler);
}
private void validate(Object[] args)
{
System.out.println("validate parameter: " + Arrays.toString(args));
}
}
package xyz.huning.spring4.aop.calculator.proxyimpl;
import xyz.huning.spring4.aop.calculator.ICalculator;
import xyz.huning.spring4.aop.calculator.PureCalculator;
public class Main {
public static void main(String[] args) {
ICalculator oc2 = new PureCalculator();
oc2 = new CalculatorLogProxy(oc2).getProxy();
oc2 = new CalculatorValidateProxy(oc2).getProxy();
oc2.add(10, 20);
oc2.sub(30, 10);
oc2.mul(10, 10);
oc2.div(20, 10);
}
}