zrl00 2015-07-12
为了解决原始实现中存在的问题,下面考虑使用动态代理来实现。
代理设计模式的原理
使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
类图
实现
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); } }