先说说两者的区别
jdk动态代理是java的标准api , 被代理的类必须实现一个或者多个接口,然后根据接口和实现类动态创建代理类,所生成的代理类是java.lang.reflect.Proxy的子类,并且也是实现类的子类(这块可能有点绕)
cglib动态代理是依靠cglib库的api ,被代理的类不用实现接口,它是以生成被代理类的子类的方法来生成代理类的。相比JDK动态代理的优势在于被代理的类不用实现任何接口就可以代理。这里要注意被代理的类不能是final。
下面先上被代理类的代码
接口
package net;
public interface ISay
{
public void say();
}
实现类
package net;
public class Person implements ISay
{
@Override
public void say()
{
System.out.println("person say.......");
}
}
下面让我们来看看JDK如何给这个类动态生成代理类,首先写一个代理的处理类,实现java.lang.reflect.InvocationHandler接口
看代码
package jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import net.ISay;
public class MyInvocationHandler implements InvocationHandler
{
//被代理的类
private ISay target;
public MyInvocationHandler(ISay target)
{
this.target = target;
}
/**
*
* @param proxy 生成的代理对象,这里要注意这个参数不是被代理类。
* 这个参数目前没有发现其作用,欢迎知道的拍砖
* @param method 被代理对象的原始方法
* @param args 方法调用所需要的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("before");
Object result = method.invoke(target, args);
System.out.println("end");
return result;
}
}
测试类
package jdk;
import java.lang.reflect.Proxy;
import net.ISay;
import net.Person;
public class Run
{
public static void main(String[] args)
{
Person p=new Person();
MyInvocationHandler mih=new MyInvocationHandler(p);
ISay proxyPerson=(ISay) Proxy.newProxyInstance(Run.class.getClassLoader(), new Class[]{ISay.class}, mih);
proxyPerson.say();
}
}
运行的测试结果
before
person say.......
end
很显然我们的person类被代理了,我们可以在它原始方法的调用前后搞出一些事情
下面我们来看看cglib如何实现动态代理,注意与jdk动态代理最大的不同
代理生成类实现net.sf.cglib.proxy.MethodInterceptor接口
package cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public abstract class CglibProxy implements MethodInterceptor
{
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> t)
{
Enhancer e = new Enhancer();
//设置代理的类的class
e.setSuperclass(t);
//设置要处理代理类方法的处理类
e.setCallback(this);
return (T) e.create();
}
/**
*
* @param obj 生成的代理对象
* @param method 被代理类的原始方法
* @param objs 调用方法的参数
* @param mp 代理类方法的对象,包含被代理类的原始方法
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable
{
before();
//这里调用父类原始的方法,也就是被代理对象的原始方法
Object result = mp.invokeSuper(obj, args);
end();
return result;
}
public abstract void before();
public abstract void end();
}
这个生成代理的类,只能生成带有无参数构造方法的类,并且被代理的类不能是final
测试方法
package cglib;
import net.Person;
public class Run
{
public static void main(String[] args)
{
// 用内部类实现
CglibProxy cp = new CglibProxy()
{
@Override
public void before()
{
System.out.println("before");
}
@Override
public void end()
{
System.out.println("end");
}
};
Person p = cp.getProxy(Person.class);
p.say();
}
}
我们来看看控制台输出了什么
before
person say.......
end
同样也可以在person原始的say方法调用前后搞出一些事情。源码在附件,附带所需的Jar包。
cglib用的3.0版本,cglib3.0所需要依赖的asm的4.0版本才可以,asm3.0会报类兼容错误,希望大家注意。
刚学习的,欢迎大大拍砖
分享到:
相关推荐
java代理机制 JDK动态代理和cglib代理 详解
java静态代理 jdk动态代理 cglib动态代理 代理原理
NULL 博文链接:https://jummy.iteye.com/blog/255628
AOP之JDK动态代理和CGLib动态代理 ,具体效果和过程看博文 http://blog.csdn.net/evankaka/article/details/45195383
jdk 的动态代理和CGLIB代理
jdk 和 cglib的简单动态代理,闲来无事 写写。有需要的朋友可以看看
JAVA动态代理实现Demo(JDK动态代理和CGLIB动态代理)
JDK代理和Cglib代理,下载源码清楚了解二者区别
实现java动态代理的两个实例,jdk动态代理和cglib
Spring框架的AOP中重要的一个知识点,动态代理,springAOP框架会根绝实际情况选择使用jdk的动态代理还是cglib的动态代理
静态代理、jdk动态代理、cglib动态代理
JDK动态代理,关于jdk动态代理的问题!详细的说明!JDK动态代理JDK动态代理
JDK动态代理和Cglib动态代理实例源码
Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理)
该资源里面有Jdk动态代理,cglib动态代理,反射和拦截器(链)示例,里面也有所需要的jar包,下载下来导入eclipse即可运行,有问题请问我
Java JDK代理、CGLIB、AspectJ代理分析比较
jdk和cglib动态代理的例子{jar包+源码} 解压:如有问题 用快压
附件为java 动态代理实例,有全码,包括测试代码。 代码少,注释全。 对理解代理非常不错。
NULL 博文链接:https://lizhao6210-126-com.iteye.com/blog/1711218