AOP面向切面的基石——动态代理(一)
其实动态代理在Java里不是什么新技术了,早在java 1.2之后便通过 java.lang.reflect.InvocationHandler 加入了动态代理机制。
下面例子中,LancerEvolutionVI是Car接口的一个实现。
CarTestModelFactory的getNewInstance接收一个LancerEvolutionVI对象,而返回一个代理对象。这个代理对象同LancerEvolutionVI一样,也实现了Car接口,在其Override实现的各个接口方法中,对LancerEvolutionVI的方法进行了拦截,并按照invoke方法中定义的那样安排各个切面方法的位置和调用顺序。
package com.proxy; public interface Car { public void speed(); public void torque(); }
package com.proxy; public class LancerEvolutionVI implements Car{ @Override public void speed() { System.out.println("LancerEvolutionVI speed is 280"); } @Override public void torque() { System.out.println("LancerEvolutionVI torque is 450"); } }
package com.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class CarTestModelFactory implements InvocationHandler{ private Car testCar; public Car getNewInstance(Car car){ this.testCar = car; Class c = car.getClass(); Car testModel = (Car)Proxy.newProxyInstance(c.getClassLoader(), c.getInterfaces(), this); return testModel; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("speed")){ System.out.println("速度测试开始..."); method.invoke(this.testCar, args); System.out.println("速度测试结束!"); }else{ System.out.println("扭矩测试开始..."); method.invoke(this.testCar, args); System.out.println("扭矩测试结束!"); } return null; } }
测试代码:
Car car = new CarTestModelFactory().getNewInstance(new LancerEvolutionVI());
car.speed();
car.torque();
运行结果:
速度测试开始...
LancerEvolutionVI speed is 280
速度测试结束!
扭矩测试开始...
LancerEvolutionVI torque is 450
扭矩测试结束!