CGLIB 和 JDK生成动态代理类的区别
2017-01-18 · 百度知道合伙人官方认证企业
CGLIB 和 JDK生成动态代理类区别
jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。
cglib这种第三方类库实现的动态代理应用更加广泛,并不需要目标类基于统一的接口,且在效率上更有优势。
下面分别用2个具体例子来详细阐述
jdk生成代理类
为目标类(target)定义统一的接口类Service,这个是jdk动态代理必须的前提
public interface Service {
/**
* add方法
*/
public void add();
/**
* update方法
*/
public void update();
}
2.目标类AService
public class AService implements Service {
/*
* (non-Javadoc)
*
* @see jdkproxy.Service#add()
*/
public void add() {
System.out.println("AService add>>>>>>>>>>>>>>>>>>");
}
/*
* (non-Javadoc)
*
* @see jdkproxy.Service#update()
*/
public void update() {
System.out.println("AService update>>>>>>>>>>>>>>>");
}
}
3.实现动态代理类MyInvocationHandler,实现InvocationHandler接口,并且实现接口中的invoke方法。在
invoke方法中加入一些代理功能。目标类方法的执行是由mehod.invoke(target,args)这条语句完成。
public class MyInvocationHandler implements InvocationHandler {
private Object target;
MyInvocationHandler() {
super();
}
MyInvocationHandler(Object target) {
super();
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 程序执行前加入逻辑,MethodBeforeAdviceInterceptor
System.out.println("before-----------------------------");
// 程序执行
Object result = method.invoke(target, args);
// 程序执行后加入逻辑,MethodAfterAdviceInterceptor
System.out.println("after------------------------------");
return result;
}
}
4.测试类,其中增强的目标对象是由Proxy.newProxyInstance(aService.getClass().getClassLoader(), aService.getClass().getInterfaces(), handler);来生成的。
public class Test {
public static void main(String[] args) {
Service aService = new AService();
MyInvocationHandler handler = new MyInvocationHandler(aService);
// Proxy为InvocationHandler实现类动态创建一个符合某一接口的代理实例
Service aServiceProxy = (Service) Proxy.newProxyInstance(aService
.getClass().getClassLoader(), aService.getClass()
.getInterfaces(), handler);
// 由动态生成的代理对象来aServiceProxy 代理执行程序,其中aServiceProxy 符合Service接口
aServiceProxy.add();
System.out.println();
aServiceProxy.update();
}
cglib动态代理实现AOP拦截
被代理目标类,cglib不需要目标类实现接口
public class Base {
/**
* 一个模拟的add方法
*/
public void add() {
System.out.println("add ------------");
}
}实现动态代理类CglibProxy,需要实现MethodInterceptor接口,实现intercept方法。
public class CglibProxy implements MethodInterceptor {
public Object intercept(Object object, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
// 添加切面逻辑(advise),此处是在目标类代码执行之前,即为MethodBeforeAdviceInterceptor。
System.out.println("before-------------");
// 执行目标类add方法
proxy.invokeSuper(object, args);
// 添加切面逻辑(advise),此处是在目标类代码执行之后,即为MethodAfterAdviceInterceptor。
System.out.println("after--------------");
return null;
}
}获取增强的目标类的工厂Factory,其中增强的方法类对象是有Enhancer来实现的
public class Factory {
/**
* 获得增强之后的目标类,即添加了切入逻辑advice之后的目标类
*
* @param proxy
* @return
*/
public static Base getInstance(CglibProxy proxy) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Base.class);
//回调方法的参数为代理类对象CglibProxy,最后增强目标类调用的是代理类对象CglibProxy中的intercept方法
enhancer.setCallback(proxy);
// 此刻,base不是单纯的目标类,而是增强过的目标类
Base base = (Base) enhancer.create();
return base;
}
}测试类
public class Test {
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
// base为生成的增强过的目标类
Base base = Factory.getInstance(proxy);
base.add();
}
}从上面2个例子,可看出cglib中目标类Base并没有实现接口,而jdk生成代理类例子中AService 实现了Service接口,所以CGLIB 和 JDK生成动态代理类的区别最大的区别就是目标类是否需要实现接口。
2023-07-25 广告