JDk 和Cglib动态代理预览
JDk 动态代理
jdk1.3以后,开发者可以在runtime期间创建接口的代理实例,动态代理是实现AOP的绝好的底层技术
涉及到java.lang.reflect 包中的两个类:Proxy ,InvocationHandler,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,横切逻辑与业务逻辑就这样编织在一起了
而proxy利用InvocationHandler动态创建符合某一接口的实例newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h),生成目标类的代理对象。
下面给出部分代码:
public class PerformanceHandler implements InvocationHandler{
private Object target;
//target为目标的业务类
public PerformanceHandler(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
PerformanceMonitor.begin(target.getClass().getName()+"."+method.getName());
//通过反射调用业务类的目标方法
Object obj = method .invoke(target, args);
PerformanceMonitor.end();
return obj;
}
}
public class TestForumService2 {
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(1003);
}
}
Cglib动态代理
针对JDK只能为接口创建代理实例,由newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h)可以看出,但对于一个简单业务表的操作不一定要创建接口(没有标准),难道不能直接通过实现类构建程序吗?(SpringSide开源项目是一个很好的例证),总的来说,Cglib弥补了JDK 动态创建代理实例的空缺。
CGLIB采用底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截技术拦截所有父类方法的调用,并顺势织入横切逻辑。
下面给出部分代码:
public class CglibProxy implements MethodInterceptor{
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
//设置要创建代理类的父类
enhancer.setSuperclass(clazz);
enhancer.setCallback((Callback) this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
// TODO Auto-generated method stub
//输出业务所调用的父类方法
EventMonitor.begin(obj.getClass().getName()+"."+method.getName());//横切逻辑
//注意这里proxy调用的是父类的方法 invokeSuper,而非invoke
Object result = proxy.invokeSuper(obj, args);
EventMonitor.end();//横切逻辑
return result;
}
}
public class TestService {
public static void main(String[] args){
CglibProxy proxy = new CglibProxy();
//采用底层字节码文件,创建RunnerServiceImpl的子类
RunnerServiceImpl runSer = (RunnerServiceImpl)proxy.getProxy(RunnerServiceImpl.class);
runSer.addRunner();
runSer.removeRunner();
}
}