JDk 和Cglib动态代理

阅读更多

JDkCglib动态代理预览
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();

}

}

 

 

你可能感兴趣的:(jdk动态代理,Cglib动态代理,spring,AOP)