1.JAVA-JDK的动态代理
代码清单6-6 PerformanceHandler
package com.baobaotao.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PerformanceHandler implements InvocationHandler {//①实现InvocationHandler
private Object target;
public PerformanceHandler(Object target){ //②target为目标的业务类
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) ③
throws Throwable {
PerformanceMonitor.begin(target.getClass().getName()+"."+ method. getName());③-1
Object obj = method.invoke(target, args);// ③-2通过反射方法调用业务类的目标方法
PerformanceMonitor.end();③-1
return obj;
}
}
package com.baobaotao.proxy;
import java.lang.reflect.Proxy;
public class TestForumService {
public static void main(String[] args) {
//①希望被代理的目标业务类
ForumService target = new ForumServiceImpl();
//②将目标业务类和横切代码编织到一起
PerformanceHandler handler = new PerformanceHandler(target);
//③根据编织了目标业务类逻辑和性能监视横切逻辑的InvocationHandler实例创建代理实例
ForumService proxy = (ForumService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler);
//④调用代理实例
proxy.removeForum(10);
proxy.removeTopic(1012);
}
}
代理对象会重写接口的方法,设想这个方法会去调用handler 的invoke方法
2.CGLib动态代理
CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势织入横切逻辑。下面,我们采用CGLib技术,编写一个可以为任何类创建织入性能监视横切逻辑代理对象的代理创建器,如代码清单 6-8所示:
package com.baobaotao.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz) {
enhancer.setSuperclass(clazz); //① 设置需要创建子类的类
enhancer.setCallback(this);
return enhancer.create(); //②通过字节码技术动态创建子类实例
}
//③拦截父类所有方法的调用
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
PerformanceMonitor.begin(obj.getClass().getName()+"."+method. getName());//③-1
Object result=proxy.invokeSuper(obj, args); ③-2
PerformanceMonitor.end();//③-1通过代理类调用父类中的方法
return result;
}
}
package com.baobaotao.proxy;
import java.lang.reflect.Proxy;
public class TestForumService {
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
ForumServiceImpl forumService = ①
(ForumServiceImpl )proxy.getProxy(ForumServiceImpl.class);
forumService.removeForum(10);
forumService.removeTopic(1023);
}
}
设想生成的代理对象(实际对象的子类对象)会重写父类的方法,里面回调了父类对象的方法
Spring AOP使用了两种代理机制:一种是基于JDK的动态代理;另一种是基于CGLib的动态代理。
猜你喜欢
转载自asadavas.iteye.com/blog/1764061
今日推荐
周排行