前几天有人问我了解Spring AOP的实现原理吗?我说Spring AOP的底层实现是基于动态代理的,是采用cglib来实现的,我视乎只是大致的知道是基于代理类的,但是具体是怎么实现的我貌似也是一知半解,今天有空上网看了下,将自己的思路写出来,谈谈自己的想法。
一、代理类主要分为
1、静态代理
2、动态代理
二、代理的主要作用大致可以总结如下:
1、保证了目标类的安全性:使用代理模式,避免了你直接操作目标对象(即:被代理的对象),你直接操作的是代理对象。
2、功能增强:我们可以将核心的业务写在目标类中,而在代理类中对目标类执行前后进行增强功能的编写,这样可以在不改变目标对象的前提下达到了功能增强的目的。
3、解耦:核心业务逻辑写在目标类中,辅助业务逻辑写在代理类中,从而达到了解耦的目的
4、简化了开发:和代理类打交道,不和目标类打交道,简化了开发
三、代理类的适用场景:
3.1、静态代理的典型应用就是Thread和Runnable
3.2、动态代理的典型应该就是Spring AOP
四、静态代理
总结下编写静态代理的步骤:第一步:将业务抽象为接口;第二步:创建代理类和目标类,让代理类和目标类都实现这个接口;第三:代理角色持有真正角色的引用,真正执行具体业务时交给目标类执行。
接口:
目标类:目标类实现了Runnable接口,并且重写了 run方法
代理类:
Thread 实现了Runnable接口,并且重写run方法
调用Thread的构造函数,传入目标类
测试类
五、动态代理
动态代理的实现有两种,一种是基于JDK的动态代理,另一种是基于cglib的动态代理。
JDK动态代理主要是利用反射机制生成一个实现代理接口的代理对象,代理对象的生成主要是利用java的api,在内存中动态的生成代理对象。代理对象不需要实现接口,目标类必须实现接口,否则无法使用基于JDK的动态代理。
具体代码如下:
定义一个实现接口的实现类
定义工厂类用于实现代理类
测试类:
六、cglib动态代理
静态代理和jdk动态代理都需要目标类实现接口,而cglib代理不需要目标类实现任何接口,目标对象只是一个单独的对象时也能使用cglib代理,cglib底层是使用ASM框架(使用cglib时需要引入asm和cglib这两个jar包),将目标对象的字节码文件加载进来,然后通过修改字节码文件创建一个子类,然后通过这个子类来实现动态代理。注意目标类不能被final修饰,因为若目标类被final修饰,cglib无法再内存中动态生成的它的子类。
代码如下:
目标类
代理工厂类
测试类:
总结:JDK动态代理和cglib动态代理的区别?
(1)、JDK动态代理只能针对实现接口的类实现动态代理
(2)、cglib可以针对无需实现接口的类实现代理,主要是针对代理类生成一个子类,然后覆盖其中的方法,因为要生成子类,所以目标类不能用fianl修饰。