tonglin0325的个人主页

SpringBoot学习笔记——动态代理

代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

 

1.静态代理: 在编译时就已经实现,编译完成后代理类是一个实际的class文件

静态代理的方式:创建一个接口,然后创建被代理的类实现该接口并且实现该接口中的抽象方法。之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法。

参考:什么是动态代理? 

2.动态代理: 在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中

动态代理的方式:JDK动态代理 和 CGLIB动态代理

在springboot 2.x中默认使用的CGLIB动态代理,如果要强制使用JDK代理的话,需要添加配置

1
2
spring.aop.proxy-target-class=false

参考:springboot2.x默认使用的代理是cglib代理

 

JDK动态代理 和 CGLIB动态代理的区别:

1.JDK动态代理只能对实现了接口的类生成代理,而不能针对类

JDK动态代理使用 java.lang.reflect.InvocationHandler,参考:Java动态代理之InvocationHandler最简单的入门教程

 

使用JDK动态代理的五大步骤:

  1. 通过实现InvocationHandler接口来自定义自己的InvocationHandler;
  2. 通过Proxy.getProxyClass获得动态代理类;
  3. 通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)
  4. 通过构造函数获得代理对象并将自定义的InvocationHandler实例对象传为参数传入;
  5. 通过代理对象调用目标方法;

2.Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,因为是继承,所以该类或方法最好不要声明成final

Cglib动态代理使用 org.springframework.cglib.proxy.*,

CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类

CGLIB代理实现如下:

  1. 首先实现一个MethodInterceptor,方法调用会被转发到该类的intercept()方法。
  2. 然后在需要使用的时候,通过CGLIB动态代理获取代理对象。

参考:【Spring教程】详解AOP的实现原理(动态代理)

什么是动态代理?

 

在SpringBoot中如何使用动态代理,参考:【Spring Boot实战与进阶】AOP的两种动态代理(JDK和Cglib)