`
SIHAIloveYAN
  • 浏览: 113301 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

JDK和cglib生成代理类

 
阅读更多

关于动态代理和静态代理

当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁–代理对象。

按照代理对象的创建时期不同,可以分为两种:

静态代理:事先写好代理对象类,在程序发布前就已经存在了;

动态代理:应用程序发布后,通过动态创建代理对象。

动态代理又可分为:JDK动态代理和CGLIB代理。

1.JDK动态代理

此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑。

代理模式在实际使用时需要指定具体的目标对象,如果为每个类都添加一个代理类的话,会导致类很多,同时如果不知道具体类的话,怎样实现代理模式呢?这就引出动态代理。

JDK动态代理只能针对实现了接口的类生成代理。

2.CGLIB代理

CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,

主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。

JDK动态代理和CGLIB代理生成的区别

JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。
因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态。

PS:final 所修饰的数据具有“终态”的特征,表示“最终的”意思:

final 修饰的类不能被继承。
final 修饰的方法不能被子类重写。
final 修饰的变量(成员变量或局部变量)即成为常量,只能赋值一次。
final 修饰的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有 一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用。
final 修饰的局部变量可以只声明不赋值,然后再进行一次性的赋值。

参考代码

CGLIB:


public Object createProxyObject(Object obj) { 
    this.targetObject = obj; 
    Enhancer enhancer = new Enhancer(); 
    enhancer.setSuperclass(obj.getClass()); 
    enhancer.setCallback(this); 
    Object proxyObj = enhancer.create(); 
    return proxyObj;// 返回代理对象,返回的对象其实就是一个封装了“实现类”的代理类,是实现类的实例。 
} 

JDK:

public Object newProxy(Object targetObject) {// 将目标对象传入进行代理 
    this.targetObject = targetObject;  <br>    //注意这个方法的参数,后面是类实现的接口
    return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), 
            targetObject.getClass().getInterfaces(), this);// 返回代理对象 
}

在代码中可以看到,在生成代理类时,传递的是实现类所实现的接口 targetObject.getClass().getInterfaces(),所以JDK只能对于接口进行做代理。如果换成类的话,则会抛java.lang.ClassCastException异常。

在Spring的源码中,可以看到很多生成代理类的代码。

动态代理的应用

AOP(Aspect-OrientedProgramming,面向切面编程),AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。

实现AOP的技术,主要分为两大类:

一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;

二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

Spring提供了两种方式来生成代理对象: JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。

默认的策略是如果目标类是接口,则使用JDK动态代理技术,如果目标对象没有实现接口,则默认会采用CGLIB代理。

如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入)。

转自:http://www.cnblogs.com/binyue/p/4519652.html

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
分享到:
评论

相关推荐

    java代理机制 JDK动态代理和cglib代理 详解

    java代理机制 JDK动态代理和cglib代理 详解

    CGLIB 和 JDK生成动态代理类的区别

    NULL 博文链接:https://luyuanliang.iteye.com/blog/1137292

    cglib创建代理类.rar

    springAOP等框架中,大量用到代理技术; 两类代理技术: 1,java动态代理,见JDK文档或相关java书;...2.cglib创建代理类,比第一种更加简单,代理类和背代理类不需要实现共同接口。本例子就是cglib代理的例子,很简单

    使用JDK与Cglib动态代理技术统一管理日志记录

    区别主要是jdk是代理接口,而cglib是代理类。 优点:这种方式已经解决我们前面所有日记需要的问题。非常的灵活。而且可以方便的在后期进行维护和升级。 缺点:当然使用jdk动态代理,必需要有接口。如果没有接口。就...

    cgLib与JDK动态代理的用法

    代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类...

    你必须会的 JDK 动态代理和 CGLIB 动态代理

    静态代理就是在程序运行之前,代理类字节码.class就已编译好,通常一个静态代理类也只代理一个目标类,代理类和目标类都实现相同的接口。 接下来就先通过 demo 进行分析什么是静态代理,当前创建一个 Animal 接口,...

    cglib 和asm jar包

    jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,...

    cglib代理资料类,静态代理动态代理

    静动态代理,cglib,jdk

    cglib.jar下载

    CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。 CGLIB底层:使用...

    cglib aop spring 动态代理

    cglib代理, 1.cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。 2.cglib封装了asm,可以在运行期动态生成新的class。 3.cglib用于AOP,...

    JDK动态代理(AOP)使用及原理分析视频教程课件

    动态代理是使用jdk的反射机制,创建对象的能力, 创建的是代理类的对象。 而不用你创建类文件。不用写java文件。 动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。jdk动态代理,必须有接口,目标类必须...

    cglib包及依赖汉cglib3.1和asm4.2

    cglib包及依赖汉cglib3.1和asm4.2,主要作用是用户代理,代理为控制要访问的目标对象提供了一种途径。当访问对象时,它引入了一个间接的层。JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。...

    cglib必须导入的包和案例

    Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展. JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现....

    基于java的企业级应用开发:JDK动态代理.ppt

    CGLIB代理 CGLIB(Code Generation Library)是一个高性能开源的代码生成包,它采用非常底层的字节码技术,对指定的目标类生成一个子类,并对子类进行增强。 如果想代理没有实现接口的类,那么可以使用CGLIB代理。 ...

    2020年春招最新阿里Java面试题集锦

    jdk和cglib实现的AOP实际上会在内存生成动态代理对象,还有什么其他办法实现AOP?经提示答出AspectJ以及实现原理 Spring中的对象的作用域 Singleton对象引用Prototype会发生什么 项目中怎样使用微服务? 两个服务...

    JDKProxy:用来理解jdk基于接口的动态代理和cglib基于类代理区别的demo

    用来理解jdk基于接口的动态代理和cglib基于类的代理的区别

    jdk动态代理修改返回类对象.rar

    熟悉动态代理的小伙伴都知道,java的动态代理有两个常用的方式,一个是jdk动态代理,一个是cglib,他们两个在使用上的最大区别就是前者是返回一个接口对象(其实质是Proxy类的子类),后者是返回了被代理类的类对象...

    Spring框架+SpringAOP动态代理

    Spring AOP 使用的动态代理主要有两种方式:JDK 动态代理和 CGLIB 代理。 JDK 动态代理:用于代理实现了接口的类。Spring 会使用 java.lang.reflect.Proxy 类来创建代理对象。 CGLIB 代理:用于代理没有实现接口的...

    aspectjrt.jar和cglib-nodep-3.1.jar

    JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。 CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。 因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态...

    spring_aop4.rar_Home Home_jar 转换_spring AOP jar

    JDK动态代理和CGLIB字节码生成的区别? * JDK动态代理只能对实现了接口的类生成代理,而不能针对类 * CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 因为是继承,所以该类或方法最好...

Global site tag (gtag.js) - Google Analytics