当前位置 博文首页 > 盛夏温暖流年:java的代理机制(静态代理和动态代理)

    盛夏温暖流年:java的代理机制(静态代理和动态代理)

    作者:[db:作者] 时间:2021-07-13 19:03

    一. 代理的概念

    为某个对象提供一个代理,以控制对这个对象的访问。

    代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、

    过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。

    从图中可以看出,代理接口(Subject)、代理类(ProxySubject)、委托类(RealSubject)形成一个“品”字结构。

    ?

    二. 代理的分类

    根据代理类的生成时间不同可以将代理分为?静态代理?和?动态代理?两种。

    静态代理

    由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前该代理类的字节码文件就已经存在,代理类和委托类的关系在运行前就确定了。?

    优点:

    业务类只需要关注业务逻辑本身,保证了业务类的重用性,这是代理的共有优点。

    缺点:

    1. 代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。?

    2. 如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。?

    静态代理--代码实现git路径:

    https://github.com/jichunyang19931023/dailyDemo/tree/master/staticProxyModel

    ?

    动态代理(Spring AOP的实现原理

    动态代理是在程序运行时,运用反射机制动态创建而成。动态代理又分为两种实现方式:JDK 动态代理?和?CGlib 动态代理?

    JDK动态代理

    JDK动态代理的代理类字节码在创建时,需要实现业务实现类所实现的接口作为参数。如果业务实现类是没有实现接口而是直接定义业务方法的话,就无法使用JDK动态代理了。(JDK动态代理重要特点是代理接口) 并且,如果业务实现类中新增了接口中没有的方法,这些方法是无法被代理的(因为无法被调用)。

    CGlib动态代理

    对于没有接口的类,需要使用CGlib来实现动态代理。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

    JDK动态代理和CGlib动态代理--代码实现git路径:

    https://github.com/jichunyang19931023/dailyDemo/tree/master/dynamicProxyModel

    JDK和CGlib两种动态代理方式区别

    1、java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而Cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

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

    3、CGlib一个目标类方法会生成两个代理方法,一个重写目标方法,并实现代理逻辑,还有一个直接调用目标类方法。

    ?

    cs