【JAVA代理专题】

[1] 什么是代理模式?

代理是一种设计模式,它的核心思想,是将对目标的访问转移到代理对象上。这样做的好处就是,目标对象在不改变代码的情况下,可以通过代理对象加一些额外的功能。这是一种编程思想,在不改变原有代码的情况下,通过代理增加一些扩展功能。

代理过程如图所示,用户访问代理对象,代理对象通过访问目标对象,来达到用户访问目标对象的目的

在这里插入图片描述

代理模式包含一下三个角色:

  • ISubject:接口对象,该接口是对象和它的代理共用的接口。
  • TargetSubject:目标对象,是实现抽象主题接口的类。
  • Proxy:代理角色,内部含有对目标对象TargetSubject的引用,从而可以操作真实对象。代理对象提供与目标对象相同的接口,以便在任何时刻都能代替目标对象。同时,代理对象可以在执行目标对象操作时,附加其他的操作,相当于对真实对象进行封装。

常见的代理模式分为静态代理动态代理,动态代理在Java中的实现分为JDK动态代理cglib代理

[2] 什么是静态代理?

静态代理:由程序员创建或工具生成代理类的源码,再编译代理类,即代理类和委托类的关系再程序运行前就已经存在。

[3] 什么是动态代理?如何实现?

动态代理:在运行期间使用动态生成字节码形式,动态创建代理类。使用的工具有 jdkproxy、cglibproxy 等。

动态代理的实现方式是借助java.lang.Reflect.Proxy进行反射实现的,其步骤如下:
a、编写一个委托类接口,对应的静态代理的Subject接口
b、编写一个委托类接口的实现类,对应的是静态代理的RealSubject
c、创建动态代理类方法调用处理程序,实现InvocationHandler接口,并重写invoke方法
d、在测试类中生成动态代理对象

[4] 静态代理和动态代理有什么区别?

在这里插å¥å›¾ç‰‡æè¿°

动态代理的应用:Spring 的 AOP 、加事务、加权限、加日志。

[5] 怎么实现动态代理?

Jdk动态对象

Jdk的动态代理由Proxy这个类来生成,注意该方法是在Proxy类中是静态方法,且接收的三个参数依次为:

  • ClassLoader loader,:指定当前目标对象使用类加载器,获取加载器的方法是固定的
  • Class<?>[] interfaces,:目标对象实现的接口的类型,使用泛型方式确认类型
  • InvocationHandler h😗*事件处理,**执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入

CGLib动态代理

CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。

上面的静态代理和动态代理模式都是要求目标对象是实现一个接口的目标对象,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以使用以目标对象子类的方式类实现代理,这种方法就叫做:Cglib代理

也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.

  • JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现.
  • Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)
  • Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.

Cglib子类代理实现方法:
1.需要引入cglib的jar文件,但是Spring的核心包中已经包括了Cglib功能,所以直接引入pring-core-3.2.5.jar即可.
2.引入功能包后,就可以在内存中动态构建子类
3.代理的类不能为final,否则报错
4.目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法.

Jdk动态对象和CGLib动态代理区别

Jdk SDK面向的是一组接口,他为这些接口创建了一个实现类。cglib代理面对的是一个具体类,搭配创建了一个新类,继承了该类重写了该方法。

[6] 动态代理的应用

动态代理在代码界可是有非常重要的意义,我们开发用到的许多框架都使用到了这个概念。我所知道的就有:Spring AOP、Hibernate、Struts 使用到了动态代理。

  • **Spring AOP。**Spring 最重要的一个特性是 AOP(Aspect Oriented Programming 面向切面编程),利用 Spring AOP 可以快速地实现权限校验、安全校验等公用操作。而 Spring AOP 的原理则是通过动态代理实现的,默认情况下 Spring AOP 会采用 Java 动态代理实现,而当该类没有对应接口时才会使用 CGLib 动态代理实现
  • **Hibernate。**Hibernate 是一个常用的 ORM 层框架,在获取数据时常用的操作有:get() 和 load() 方法,它们的区别是:get() 方法会直接获取数据,而 load() 方法则会延迟加载,等到用户真的去取数据的时候才利用代理类去读数据库。
  • **Struts。**Struts 现在虽然因为其太多 bug 已经被抛弃,但是曾经用过 Struts 的人都知道 Struts 中的拦截器。拦截器有非常强的 AOP 特性,仔细了解之后你会发现 Struts 拦截器其实也是用动态代理实现的。
[7] Spring如何实现AOP?
  1. AnnotationAwareAspectJAutoProxyCreator是AOP核心处理类
  2. AnnotationAwareAspectJAutoProxyCreator实现了BeanProcessor,其中postProcessAfterInitialization是核心方法。
  3. 核心实现分为2步 getAdvicesAndAdvisorsForBean获取当前bean匹配的增强器 createProxy为当前bean创建代理
  4. getAdvicesAndAdvisorsForBean核心逻辑如下 a. 找所有增强器,也就是所有@Aspect注解的Bean b. 找匹配的增强器,也就是根据@Before,@After等注解上的表达式,与当前bean进行匹配,暴露匹配上的。 c. 对匹配的增强器进行扩展和排序,就是按照@Order或者PriorityOrdered的getOrder的数据值进行排序,越小的越靠前。
  5. createProxy有2种创建方法,JDK代理或CGLIB a. 如果设置了proxyTargetClass=true,一定是CGLIB代理 b. 如果proxyTargetClass=false,目标对象实现了接口,走JDK代理 c. 如果没有实现接口,走CGLIB代理
[8] 静态代理和动态代理的区别

很明显的是:

  • 静态代理需要自己写代理类–>代理类需要实现与目标对象相同的接口
  • 而动态代理不需要自己编写代理类—>(是动态生成的)

使用静态代理时:

  • 如果目标对象的接口有很多方法的话,那我们还是得一一实现,这样就会比较麻烦

使用动态代理时:

  • 代理对象的生成,是利用JDKAPI,动态地在内存中构建代理对象(需要我们指定创建 代理对象/目标对象 实现的接口的类型),并且会默认实现接口的全部方法

link :01234
https://www.zhihu.com/question/40536038/answer/685995295
https://cloud.tencent.com/developer/article/1009203
https://cloud.tencent.com/developer/article/1524189
https://www.zhihu.com/question/40536038/answer/676236311
https://cloud.tencent.com/developer/article/1524189

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值