• AOP——基本概念、底层原理


    AOP详解



    AOP中的相关概念

    在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。

    简单的来说:

    • 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

    • 通俗描述:不通过修改源代码方式,在主千功能里面添加新功能

    例如:我需要在用户登陆模块新增一个权限判断的功能,通过面向切面就能完美实现
    在这里插入图片描述

    一些比较专业的概念定义:

    • Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的
      Advice。

    • Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。

    • Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。

    • Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。

    • Target(目标对象):织入 Advice 的目标对象.。

    • Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程


    AOP底层原理是什么?

    AOP底层使用动态代理,分为有接口和无接口两种情况进行动态代理

    1)有接口情况JDK动态代理——调用newProxyInstance方法

    在这里插入图片描述
    2)无接口情况
    在这里插入图片描述

    JDK动态代理

    调用newProxyInstance方法
    在这里插入图片描述

    该方法有三个参数

    • 第一参数:类加载器
    • 第二参数:增加方法所在的类
    • 第三参数:实现InvocationHandler接口,创建代理对象,写增强的方法

    案例

    1)创建接口,定义方法

    package com.springAOP;
    
    public interface UserDao {
        public int add(int a ,int b);
    
        public String updata (String id);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2)创建接口实现类,实现方法

    package com.springAOP;
    
    public class UserDaoImpl implements UserDao{
        @Override
        public int add(int a, int b) {
            return a+b;
        }
    
        @Override
        public String updata(String id) {
            return id;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3)使用Proxy类创建接口代理对象

    package com.springAOP;
    
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Arrays;
    
    public class JDKProxy {
        public static void main(String[] args) {
    
    //        创建接口实现类代理
            Class[] interfaces = {UserDao.class};
            /**
             * 三个参数
             * 1.系统类加载器,通过ClassLoader.getSystemClassLoader()获得
             * 2.需要增强方法所在的类,这个类实现的接口
             * 3.实现InvocationHandler接口,增强方法体
             */
            UserDao userDao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(new UserDaoImpl()));
    //        int add = userDao1.add(1, 2);
            /**
             * 测试add和updata方法
             */
            System.out.println("add返回值:" + userDao.add(3, 5));
            System.out.println("-------------------------------------");
            System.out.println("updata返回值:" + userDao.updata("test"));
        }
    }
    
    //创建代理对象代码
    class UserDaoProxy implements InvocationHandler {
    
        //    把创建的是谁的代理对象,把谁传递过来,该案例中创建的是UserDaoImpl的代理对象,写的通用一点就用object
    //    有参数构造传递
        private Object obj;
    
        public UserDaoProxy(Object obj) {
            this.obj = obj;
        }
    
        //增强的逻辑,目前逻辑是在方法执行前后做一个输出
        @Override
        /**
         * proxy:代理对象
         * method:当前方法
         * args:参数值列表
         */
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //        方法之前
            System.out.println("方法之前执行......" + method.getName() + "传递的参数:" + Arrays.toString(args));
    //        执行被增强的方法
            /**
             * invoke:
             * 第一个为对象
             * 第二个为参数
             */
            Object invoke = method.invoke(obj, args);
            if (method.getName().equals("add")) {
                System.out.println("执行的是add方法");
            } else if (method.getName().equals("updata")) {
                System.out.println("执行的是updata方法");
            }
    //        方法之后
            System.out.println("方法之后执行" + obj);
    
            return invoke;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    spring帮我们把aop代码做了封装,我们直接进行配置就行,后续再更新

  • 相关阅读:
    【接口测试】Postman(一)--接口测试知识准备
    非零基础自学Golang 2 开发环境 2.4 Git 安装
    基于Python的人脸互换系统设计与实现
    数字三角形模型(动态规划)
    Go--结构体
    网工内推 | 运维专场,厂商、软考证书优先,五险一金,节日福利
    【Java 进阶篇】Java Session 原理及快速入门
    一文带你透析zookeeper原理
    MySQL连接方式: Unix套接字 & TCP/IP
    粗俗解释C# 8.0+的变量后面有?问号是什么意思?
  • 原文地址:https://blog.csdn.net/weixin_56696646/article/details/125899938