Spring AOP的底层实现是怎样的?

以你之姓@ 2022-11-22 05:27 224阅读 0赞

文章目录

  • Spring AOP底层实现
    • 静态代理
    • 动态代理
      • 1、JDK动态代理(必须有接口)
        • 实例:
      • 2、CGLIB动态代理(不需要类继承任何接口,字节码技术)
        • 实例:

Spring AOP底层实现

代理设计模式:将委托类融入到代理类中。

静态代理

一个接口,两个实现类,代理实现类组合真实实现类

一种根据上面的理论,很自然会想到的一种不依赖于其他技术的代理模式实现方式。而他的实现过程如下图。
在这里插入图片描述

动态代理

动态代理的动态, 就是可以动态的切换真实实现类, 也就是说可以一个代理类(相同的代码, 相同的增强操作)应对一堆不确定的真实实现类.

1、JDK动态代理(必须有接口)

通过实现InvocationHandlet接口,并重写里面的invoke方法,通过为proxy类指定classLoader和一组interfaces来创建动态代理。

JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了

动态代理就是为了解决静态代理不灵活的缺陷而产生的。静态代理是固定的,一旦确定了代码,如果委托类新增一个方法,而这个方法又需要增强,那么就必须在代理类里重写一个带增强的方法。而动态代理可以灵活替换代理方法,动态就是体现在这里。
在这里插入图片描述

JDK动态代理具体实现原理:

  1. 1、通过实现InvocationHandlet接口创建自己的调用处理器
  2. 2、通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理
  3. 3、通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型
  4. 4、通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入

实例:

  1. public interface TargetClass {
  2. void sayHello();
  3. }
  4. public class TargetClassImpl implements TargetClass{
  5. public void sayHello() {
  6. System.out.println("你好");
  7. }
  8. }
  9. public class JdkProxy implements InvocationHandler {
  10. private TargetClass targetClass;
  11. public Object createProxy(TargetClass targetClass){
  12. //传入真实实现类, 本身要做的事情会由他自己做, 代理类会额外进行其他增强操作
  13. this.targetClass = targetClass;
  14. //获取本类类加载器
  15. ClassLoader classLoader = JdkProxy.class.getClassLoader();
  16. ///获取被代理对象的所有接口
  17. Class[] clazz = targetClass.getClass().getInterfaces();
  18. System.out.println(clazz.length);
  19. //生成代理类并返回
  20. return Proxy.newProxyInstance(classLoader, clazz, this);
  21. }
  22. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  23. System.out.println("JDKProxy前置增强");
  24. Object obj = method.invoke(targetClass,args);
  25. System.out.println("JDKProxy后置增强");
  26. return obj;
  27. }
  28. }
  29. public class Test {
  30. public static void main(String[] args) {
  31. JdkProxy jdkProxy = new JdkProxy();
  32. TargetClass targetClass = new TargetClassImpl();
  33. TargetClass targetClass1 = (TargetClass) jdkProxy.createProxy(targetClass);
  34. targetClass1.sayHello();
  35. }

2、CGLIB动态代理(不需要类继承任何接口,字节码技术)

CGlib包在Spring core包里。

CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
在这里插入图片描述

实例:

  1. public class CGlibTaretClass {
  2. public void sayHello(){
  3. System.out.println("我是CGlib,我不需要接口");
  4. }
  5. }
  6. package CGlibProxyTest;
  7. import org.springframework.cglib.proxy.Enhancer;
  8. import org.springframework.cglib.proxy.MethodInterceptor;
  9. import org.springframework.cglib.proxy.MethodProxy;
  10. import java.lang.reflect.Method;
  11. public class CGlibProxy implements MethodInterceptor{
  12. //代理方法
  13. public Object createProxy(Object target){
  14. //创建一个动态类对象
  15. Enhancer enhancer = new Enhancer();
  16. //确定要增强的类,设置期父类
  17. enhancer.setSuperclass(target.getClass());
  18. //添加回调函数
  19. enhancer.setCallback(this);
  20. //返回创建的代理类
  21. return enhancer.create();
  22. }
  23. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  24. System.out.println("CGlib前置增强");
  25. Object obj = methodProxy.invokeSuper(o,objects);
  26. System.out.println("CGlib后置增强");
  27. return obj;
  28. }
  29. }
  30. public class Test {
  31. public static void main(String[] args) {
  32. CGlibProxy cGlibProxy = new CGlibProxy();
  33. CGlibTaretClass cGlibTaretClass = new CGlibTaretClass();
  34. CGlibTaretClass cGlibTaretClass1 = (CGlibTaretClass)cGlibProxy.createProxy(cGlibTaretClass);
  35. cGlibTaretClass1.sayHello();
  36. }

发表评论

表情:
评论列表 (有 0 条评论,224人围观)

还没有评论,来说两句吧...

相关阅读

    相关 AOP底层实现

    AOP是目前Spring框架中的核心之一,在应用中具有非常重要的作用,也是Spring其他组件的基础。它是一种面向切面编程的思想。关于AOP的基础知识,相信多数童鞋都已经了如

    相关 Spring AOP底层实现技术

    AOP概述   软件的编程语言最终的目的就是用更自然更灵活的方式模拟世界,从原始机器语言到过程语言再到面向对象的语言,我们看到编程语言在一步步用更自然、更强大的方式描述软件。