美文网首页
Spring AOP

Spring AOP

作者: 茶理思 | 来源:发表于2020-01-04 21:25 被阅读0次

    注:本篇原自学习记录于周冠亚、黄文毅的《Spring 5企业级开发实战》

    AOP(Aspect Oriented Programming,面向切面编程)


    动态代理,相对于静态代理而提出了的设计模式
    Spring中,有两种动态代理:JDK、CGLIB
    静态代理,一个代理类只能代理一个对象
    JDK动态代理,动态生成,被代理对象必须实现接口 InvocationHandler
    CGLIB动态代理,直接对Java类进行代理,需实现接口 MethodInterceptor

    代理,给目标对象提供一个代理对象,通过代理对象去控制目标对象
    怎么做到的呢,设计模式+反射

    // JDK 动态代理为例
    public interface Animal { 
        void eat();
    }
    public class Dog implements Animal {
        @Override
        public void eat() {
            System.out.println("Dog需要吃骨头");
        }
    }
    public class AnimalInvocationHandler implements InvocationHandler {
        /**
         * 被代理对象
         */
        private Object target;
    
        /**
         * 绑定业务对象并返回一个代理类
         * @param target
         * @return
         */
        public Object bind(Object target) {
            this.target = target;
            //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
    
        /**
         * 接口方法
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result=null;
            //方法执行前加一段逻辑
            System.out.println("——————调用前处理——————");
            //调用真正的业务方法
            result=method.invoke(target, args);
            //方法执行前加一段逻辑
            System.out.println("——————调用后处理——————");
            return result;
        }
    }
    public class JDKDynamicProxyDemo {
        public static void main(String[] args) {
            //被代理对象
            Dog dog = new Dog();
            //动态代理类对象
            AnimalInvocationHandler animalInvocationHandler = new AnimalInvocationHandler();
            //代理对象
            Animal proxy = (Animal) animalInvocationHandler.bind(dog);
            proxy.eat();
        }
    }
    

    以上就是Spring AOP的基本原理,只是Spring不需要开发人员自己维护代理类,其已帮开发人员生成了代理类。Spring AOP的实现是通过在程序运行时,根据具体的类对象和方法等信息动态地生成了一个代理类的class文件的字节码,再通过ClassLoader将代理类加载到内存中,最后通过生成的代理对象进行程序的方法调用。

    • AOP联盟


      image.png

    AOP是OOP的补充、完善

    OOP:Object Oriented Programming

    为啥会有AOP?
    在OOP中,非核心、又通用的功能(日志、监控等)代码散落各处,重复且不利复用
    将多个对象的公共模块分装成一个模块,形成一个Aspect

    相关概念

    • 横切关注点

    方法拦截,增强原来方法

    • 切面 Aspect

    横切关注点的抽象

    • 连接点 JoinPoint

    程序执行中特定的点,Spring只支持方法类型的连接点,所有Spring AOP的连接点总表示一个方法的执行

    • 切入点 Pointcut

    切入点是匹配连接点的拦截规则,切入点表达式如何和连接点匹配是AOP的核心,Spring默认使用AspectJ切入点语法

    • 通知 Advice

    拦截特定的连接点之后的动作

    • 目标对象 Target Object

    需进行增强的对象

    • 织入 Weaving

    把切面作用到目标对象,然后产生一个代理对象的过程。

    • 引入 Introduction

    不需为类实现一个接口,就能使用接口中的方法。


    AOP实现

    JDK
    • XML配置
    • 注解
    CGLIB
    • XML配置
    • 注解

    Q:execution表达式


    image.png
    @Pointcut("execution(* com.test.aop.cglib.annotation.*.*(..))")
    public void location() {}
    

    返回类型是*
    方法名是在那个包下的都可以
    参数是任意的


    基于Spring AOP的实战

    image.png
    • 增强类型

      • 前置
      • 后置
      • 环绕
      • 异常抛出
      • 引介
    • 切入点

      • 静态方法切入点StaticMethodMatcherPointcut
      • 动态方法切入点DynamicMethodMatcherPointcut
      • 注解切入点AnnotationMatchingPointcut
      • 表达式切入点ExpressionPointcut
      • 流程切入点ControlFlowPointcut
      • 复合切入点ComposablePointcut
      • 标准切入点TruePointcut


        image.png

    Spring集成AspectJ

    AspectJ是一个面向切面的框架,其可以生成遵循Java字节码规范的Class文件。
    Spring AOP和AscpectJ之间的关系:Spring使用了和AspectJ一样的注解,并使用AspectJ来做切入点解析和匹配。但是Spring AOP运行时并不依赖于AspectJ的编译器或者织入器等特性。

    image.png
    • args/@args(入参)

    • annotation(特定注解)

    • execution


      image.png
    • target/@target

    • this

    this不仅可以匹配Listener接口中定义的方法,而且还可以匹配FoodFactory中的方法
    target仅仅匹配Listener中定义的方法。

    • within/@within

    Spring AOP的实现原理

    Spring AOP的实现是通过创建目标对象的代理类,并对目标对象进行拦截来实现的

    image.png
    • ProxyFactoryBean类:功能是创建声明式的代理对象。
    • ProxyFactory类:功能是创建编程式的代理对象。
    • AspectJProxyFactory类:功能是创建基于AspectJ的代理对象。

    相关文章

      网友评论

          本文标题:Spring AOP

          本文链接:https://www.haomeiwen.com/subject/acvfactx.html