1.静态代理
只能静态的代理某些类或某些方法,功能较弱,但是编码简单,一般不推荐使用
interface A 定义功能 ,
ClassB implement interface A (实现功能),
代理类ProxyClass implement interface A ,构造方法里初始化 interface A类型的对象,然后重写实现功能(调用接口A中的方法)
使用:创建代理类ProxyClass的对象(用ClassB的对象来初始化)
简单继承,聚合接口对象(多态) 两种方式
2.Proxy动态代理 (spring aop的主要原理,cglib也有使用)
与静态代理相比,动态代理有更多优势,动态代理不仅不需要定义代理类,甚至可以在运行时指定代理类的执行逻辑,从而大大提升系统的灵活性。
JDK自带,不需要第三方依赖,可以对多个不同接口进行增强,通过反射读取注解时,只能读取到接口上的注解
原理:面向接口,只能对被实现的借口中定义的方法进行增强。
在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象
使用:
(1)和静态代理相同,首先定义一个接口
(2)创建被代理的类
(3)创建代理类,这个类实现InvocationHandler接口(重写 invoke 方法),并持有一个被代理类的对象,InvocationHandler中有一个invoke方法,所有执行代理对象的方法都会被替换成执行invoke方法。然后通过反射在invoke方法中执行代理类的方法。在代理过程中,在执行代理类的方法前或者后可以执行自己的操作,这就是spring aop的主要原理。
(4)创建动态代理对象
3.CGLIB动态代理(子类代理)
是借助ASM来实现的
特点:需要导入第三方依赖(cglib的jar包包含在Spring的核心包中),
面向父类的动态代理,对类(不是某个接口的实现类)进行增强
原理:面向父类,通过子类继承父类并重写父类方法实现增强
实现方式:通过在内存中构建一个子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,然后加入自己需要的操作。因为使用的是继承的方式,所以不能代理final 类。
实现方法:
(1)创建被代理类
(2)创建代理工厂类,实现 MethodInterceptor,用于方法的拦截回调
代码参考:java动态代理_飞!!!!的博客-CSDN博客 Java 动态代理详解 - whirlys - 博客园
总结:Proxy动态代理与CGLib动态代理都是实现Spring AOP的基础。
如果加入容器的目标对象有实现接口,用动态代理,
如果目标对象没有实现接口,用Cglib代理。