2222222222222222222222222222
测试 cglib
返回代理类
cglib动态代理实现
proxy.invokeSuper(obj,args)
cglib vs jdk
JDK动态代理机制:只能代理实现某些接口的类,如果没有实现接口的类则不能使用JDK动态代理。
cglib动态代理机制:针对类产生代理,原理就是为指定的目标类产生一个子类,子类通过方法拦截技术(覆盖父类的方法来实现功能的增强)拦截所有父类方法的调用(因为该种方式是使用继承方式,所以不能对final修饰的类进行代理)。
测试,创建CglibProxy()代理类型的实例,调用代理方法,传入被代理的 .class 类 ;方法中根据该类型执行相关的逻辑执行Train类的实例化;最后由代理的实例化对象调用move()方法
代理类的拦截代理方, intercept 中根据获得的代理类,有代理类实现目标类的Method
cglibproxy代理: 实现MehodInterceptor 方法拦截接口,并实现intercept(参数1,餐数2,参数3)方法
使用cglib动态产生代理
JDK动态代理机制:只能代理实现某些接口的类,如果没有实现接口的类则不能使用JDK动态代理。
cglib动态代理机制:针对类产生代理,原理就是为指定的目标类产生一个子类,子类通过方法拦截技术(覆盖父类的方法来实现功能的增强)拦截所有父类方法的调用(因为该种方式是使用继承方式,所以不能对final修饰的类进行代理)。
CGLIB产生代理案例:
步骤1:导入cglib的jar包。
步骤2:创建一个Train类,它并没有实现某个接口,并提供给它一个move方法。
步骤3:创建一个CglibProxy类来产生代理,它需要实现接口MethodInterceptor,并实现了intercept方法,该方法作用就是拦截所有目标类方法的调用(第一个参数:目标类的实例。第二个参数:目标方法的反射对象。第三个参数:目标方法的参数。第四个参数:Proxy代理类的实例)。

调用被代理类的方法:在intercept方法中,通过代理类实例的invokeSuper(obj,m)方法调用父类的方法,第一个参数就是目标类的对象。第二个参数是目标类方法的参数。(因为cglib是使用继承的方式实现动态代理,所以产生的代理类是被代理类的子类)
该方法需要返回该代理

步骤5:由于调用intercept方法中需要传入代理类实例,所以在该类中需要提供得到代理类实例的方法,创建代理类需要使用Enhancer属性,而且通过Enhancer创建代理类还需要传入被代理类的类类型,enhancer.setSuperclass(被代理类的类类型),表示要创建哪一个类的代理,在创建代理实例之前,还需要调用回调函数enhancer.setCallback(this),最后返回代理实例enhancer.create();

测试:首先需要创建拥有返回代理类实例方法的对象,通过这个对象调用返回代理实例的方法,然后赋值给该类,再调用方法。

cglib 动态代理
静态代理:继承、聚合 动态代理:JDK、cglib JDK动态代理:只能对实现了接口的类实现代理 ,没有接口就不能实现JDK动态代理 CGLIB动态代理:针对类产生子类,通过方法拦截技术拦截所有的父类方法的调用
四、cglib动态代理
1、针对类来实现代理。
2、对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用。
3、final修饰的类不能被继承,所以不能被代理。
4、class CglibProxy implements MethodInterceptor
intercept(Object obj,Method m,Object[] args,MethodProxy proxy);
参数说明:
obj:目标类的实例
m:目标方法的反射对象
args:方法的参数
proxy:代理类的实例
cglib jdk
JDK自从1.3版本开始,就引入了动态代理,JDK的动态代理用起来非常简单,但是它有一个限制,就是使用动态代理的对象必须实现一个或多个接口 。如果想代理没有实现接口的类可以使用CGLIB包。 CGLIB(Code Generation Library)是一个开源项目。是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Hibernate用它来实现PO(Persistent Object 持久化对象)字节码的动态生成。 注意:CGLIB不能对“final”修饰的类进行代理。 相关代码——(下): @CglibProxy.java public class CglibProxy implements MethodInterceptor { private Enhancer enhancer=new Enhancer(); public Object getProxy(Class cls){ //设置创建子类的类 enhancer.setSuperclass(cls); enhancer.setCallback(this); return enhancer.create(); } /** * 参数:object:拦截所有目标类方法的调用,method:目标方法的反射对象,args:方法的参数,methodproxy:代理类的实例。 */ public Object intercept(Object object, Method method, Object[] args, MethodProxy methodproxy) throws Throwable { syso("日志开始..."); methodproxy.invokeSuper(object, args); syso("日志结束..."); return null; } }
实战报错:

原因如下:导入包不全

报错分析:
NoClassDefFoundError发生在JVM在动态运行时,根据你提供的类名,在classpath中找到对应的类进行加载,但当它找不到这个类时,就发生了java.lang.NoClassDefFoundError的错误,而ClassNotFoundException是在编译的时候在classpath中找不到对应的类而发生的错误
JDK动态代理和CGLIB动态代理的区别
jdk动态代理和cglib动态代理的区别