Aop的实现提供了两种代理:
- JDK动态代理
- CGLIb动态代理
JDK动态代理:只能为接口创建代理实例
CGLib动态代理:一个创建处理器能为所有的类创建代理实例.
CGLIB实现原理:是因为CGLIB采用底层的字节码技术,可以为类创建一个子类,在子类中采用方法拦截的技术,拦截所有父类方法的调用,再顺势织入横切逻辑.
1.JDK实现动态代理
public interface ForumService { public int remove(int id); public void removeAll(); }
public class ForumServiceImpl implements ForumService{ @Override public int remove(int id) { System.out.println(id+"删除成功"); return id; } public void removeAll() { throw new RuntimeException("运行异常"); } }
/** * 性能监听 * @author Administrator * */ public class MethodPerformace { private long begin; private long end; private String serviceMethod; public MethodPerformace(String serviceMethod) { super(); this.serviceMethod = serviceMethod; this.begin=System.currentTimeMillis(); } public void printPerformace() { end=System.currentTimeMillis(); long elapse=end-begin; System.out.println(serviceMethod+"花费了"+elapse+"多少秒"); } }
public class PerformanceHandler implements InvocationHandler{ private Object target; /** * proxy 是最终生成的代理模式 * method 是被代理目标实例的某个具体方法,通过它可以发起目标实例方法的反射调用 * args 是被代理实例某个方法的入参,在方法反射调用时使用 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { PerformanceMonitor.begin(target.getClass().getName()+"."+method.getName()); Object obj = method.invoke(target, args); PerformanceMonitor.end(); return obj; } public PerformanceHandler(Object target) { super(); this.target = target; } }
/** * 性能监视器 * @author Administrator * */ public class PerformanceMonitor { //通过一个ThreadLocal保存与调用线程相关的性能监视信息 private static ThreadLocal<MethodPerformace> local=new ThreadLocal<MethodPerformace>(); //启动对某一目标方法的性能监测 public static void begin(String method) { System.out.println("begin monitor..."); MethodPerformace performace=new MethodPerformace(method); local.set(performace); } public static void end() { System.out.println("end monitor..."); MethodPerformace mp = local.get(); mp.printPerformace(); } }
public class FourmServiceTest {
@Test
public void proxy() {
ForumService target = new ForumServiceImpl(); // 目标业务类
PerformanceHandler handler = new PerformanceHandler(target);
ForumService proxy = (ForumService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), handler);
proxy.remove(0);
}
}
2.CGLib实现动态代理
public class CGLibProxy implements MethodInterceptor{ private Enhancer enhancer=new Enhancer(); public Object getProxy(Class clazz) { enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { PerformanceMonitor.begin(obj.getClass().getName()+"."+method.getName()); Object result = proxy.invokeSuper(obj, args); PerformanceMonitor.end(); return result; } }
public class FourmServiceTest { @Test public void cgLibProxy() { CGLibProxy proxy=new CGLibProxy(); ForumService forumService=(ForumServiceImpl)proxy.getProxy(ForumServiceImpl.class); forumService.remove(0); } }