Spring中AOP

2023-10-27

1.概述

AOP(面向切面编程):将程序中的非业务代码抽取 , 在不修改业务代码的前提下, 为其添加功能(功能增强) ,面向切面的编程思想底层是为目标创建一个代理对象,让代理对象调用目标类中方法 , 在代理对象调用时, 可以额外的调用其他的方法(增强的方法,通知)

功能: 提高代码复用率, 灵活性, 提高开发效率, 降低业务代码和非业务代码耦合度

核心原理: 使用动态代理的方式在执行方法前后或者出现异常的时候加入相关的逻辑

注意: AOP是对OOP(面向对象)补充 , 不是spring中特有的,是Java中的 一种代理思想

 2.AOP中常见的专业术语

连接点: 类中可以被增强的方法(例如新增, 修改...)

切入点: 实际被增强了的方法,

通知(Advice) : 方法被增强的功能(日志, 事务管理, 权限验证) 通知可以被分为前置通知,后置通知, 异常通知, 最终通知, 环绕通知

切面(Aspect): 把通知添加到切入点的整个过程称为切面.

目标(Target): 代理的目标对象(连接点,切入点所在类) 真正做这件事的类

代理(Proxy): 向目标对象应用通知时创建的代理对象, 代理对象,帮助我们调用通知的那个对象

3.AOP的搭建使用

3.1xml方式

1> 导入AOP的jar包

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

2> spring.xml中配置

 

 


    <!-- AOP配置引入 连接点-->
    <bean id="commonUtil" class="com.ffyc.sping.util.CommonUtil"></bean>

    <!--
          配置通知与切入点之间的关系
    -->
    <aop:config>
        <!--
            指定切入点  *代表所有  (..) 表示方法的参数 其中的.. 表示任意参数
        -->
        <!--        <aop:pointcut id="allmethod" expression="execution  (* com.ffyc.sping.dao.AdminDao.insertAdmin(..))"/>-->

        <aop:pointcut id="allmethod" expression="execution (* com.ffyc.sping.dao.*.*(..))"/>

        <!--
            配置通知和切入点
            before 前置通知, 在方法执行之前 被调用
            after  最终通知 相当于finally 无论方法是否成功执行完成,都会被调用
            after-returning 后置通知 方法正常执行后被调用
            after-throwing 异常通知,当方法中出现异常时,才会被调用
        -->
        <aop:aspect ref="commonUtil">
<!--            <aop:before method="saveLog" pointcut-ref="allmethod"></aop:before>-->
<!--            <aop:after method="saveLog" pointcut-ref="allmethod"></aop:after>-->
            <!--            <aop:after-returning method="saveLog" pointcut-ref="allmethod"></aop:after-returning>-->
            <!--            <aop:after-throwing method="saveLog" pointcut-ref="allmethod" throwing="e"></aop:after-throwing>-->

            <!--环绕通知 更加灵活 强大 -->
            <aop:around method="saveLog" pointcut-ref="allmethod"></aop:around>
        </aop:aspect>
    </aop:config>
</beans>

3> CommonUtil.java

package com.ffyc.sping.util;

import org.aspectj.lang.ProceedingJoinPoint;
import java.util.Arrays;
import java.util.Date;

public class CommonUtil {
  // Joinpoint 表示实际方法 连接点 其他四种通知
//    public void saveLog(JoinPoint joinpoint,Throwable e) {
//        Object[] objects = joinpoint.getArgs(); // 获得连接点 中的参数
//        System.out.println(Arrays.toString(objects));
//        System.out.println("时间:" + new Date());
//        System.out.println(e.getMessage());
//    }

  // 环绕通知测试
  public void saveLog(ProceedingJoinPoint joinpoint) {
      System.out.println("前置通知");
      try {
          Object[] objects = joinpoint.getArgs(); // 获得连接点 中的参数
          System.out.println(Arrays.toString(objects));
          System.out.println("时间:" + new Date());
          // 调用目标的切入点
          joinpoint.proceed(); // 不写就会没有异常通知
          System.out.println("后置通知");
      } catch (Throwable e) {
          System.out.println(e.getMessage() + " 异常通知!!!");
      }
      System.out.println("最终通知");
  }
}

3.2注解标签方式

1> spring.xml文件中开启自动代理

<!--开启自动代理-->
<aop:aspectj-autoproxy/>

2> CommonUtil.java

package com.ffyc.sping.util;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Date;
/*
    @Component 是一个通用的注解,用于将一个类标记为一个组件,
    表示这个类是一个受Spring容器管理的Bean。
    Spring容器会自动扫描并将这个类实例化为一个Bean,并将其纳入到容器的管理中。
 */
@Component
@Aspect //用于声明切面的注解
public class CommonUtil {

    //环绕通知
//    @Around(value = "execution(* com.ffyc.sping.dao.*.*(..))")
//    public void saveLog(ProceedingJoinPoint joinPoint){
//        try{
//            System.out.println("前置通知");
//            joinPoint.getArgs(); // 获得方法参数
//            joinPoint.proceed();//调用目标的切入点, 方便获得切入点中错误
//            System.out.println("后置通知");
//        }catch (Throwable e){
//            System.out.println("异常通知!!! "+e.getMessage());
//        }
//            System.out.println("最终通知");
//    }

//    @Before("execution(* com.ffyc.sping.dao.*.*(..))")
    @After("execution(* com.ffyc.sping.dao.*.*(..))")
//    @AfterReturning("execution(* com.ffyc.sping.dao.*.*(..))")
//    @AfterThrowing(value = "execution(* com.ffyc.sping.dao.*.*(..))",throwing = "e")
    public void saveLog() {
        System.out.println("保存时间:" + new Date());
    }

}

4.使用案例

事物处理: 开启事务, 关闭事务, 出现异常后回滚事务

权限判断: 在执行方法前, 判断是否具有权限

日志: 在执行前进日志处理

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring中AOP 的相关文章

随机推荐

  • jenkins配置sonar并扫描C#代码

    背景 我的jenkins搭在linux上 1 下载插件 下载插件sonarqube scanner 用来集成sonarqube 在配置任务的时候才有sonarscanner的选项 2 全局工具配置 全局工具配置windows本地的msbui
  • qt系列-qt6在线安装慢的问题

    qt unified windows x64 online exe mirror https mirrors aliyun com qt 下载速度飞快
  • Qt贪吃蛇(代码裸写,不用creator)

    先上个图哇 图1 第一关视图 图2 第二关视图 游戏说明 1 每关只需吃20颗红果即可通关 2 增加新场景 在第二关出现 3 增加刚打开程序READY状态 按空格开始 4 增加暂停功能 在程序运行中按空格暂停 再按空格继续游戏 5 只要不关
  • Python客户端发布订阅MQTT云代理消息

    MQTT基础 MQTT 是一种开放且简单的客户端服务器发布 订阅消息传输协议 专为高延迟和低网络带宽环境下不同设备之间的机器对机器通信而设计 机器对机器通信 这很容易 一个系统需要与其他系统交换信息 在物联网环境中 设备之间的通信需求急剧增
  • react native 使用echarts做面积图

    react native 使用echarts 我用到了一个组件 react native secharts https github com shifeng1993 react native secharts 使用 import Echar
  • Git合并的代码 不提交服务器的方法

    使用Git下载代码的时候 常遇到合并的情况 然后再上传的时候 系统就会自动把合并代码的过程也上传 有时候会感觉非常的烦Merge remote tracking branch choose remote name master 每次先下载到
  • pycharm自定义多行注释的颜色

  • JWT续期问题,ChatGPT解决方案

    JWT JSON Web Token 通常是在用户登录后签发的 用于验证用户身份和授权 JWT 的有效期限 或称 过期时间 通常是一段时间 例如1小时 过期后用户需要重新登录以获取新的JWT 然而 在某些情况下 用户可能会在JWT到期之前使
  • DirectShow应用——支持Windows Media格式

    大家知道 微软定义了自己的一种媒体文件类型 叫做ASF Advanced Systems Format ASF其实是一个文件 容器 它本身并没有规定音视频的压缩格式 在ASF文件中 我们可以包含任何格式的压缩的 包括MPEG 4 或非压缩的
  • 抽象工厂设计模式的扩展

    american com itheima pattern factory config factory AmericanCoffee latte com itheima pattern factory config factory Latt
  • 【Apache Spark 】第 11 章使用 Apache Spark 管理、部署和扩展机器学习管道

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • git分支合并错误回滚

    1 合并 比如testB分支合并testA分支 2 还原 如果合并时 代码有错误 已经提交的远程分支 可以参考tortoisegit 还原到某个版本 强制还原 3 重新合并 可重新执行合并流程 改过错误代码后 重新提交的远程分支
  • Java异常类详解

    目录 异常简介 异常体系 异常的处理 自定义异常类 一 异常简介 1 1 异常定义 异常是运行程序的过程中产生的异常情况 异常的情况是指程序在运行过程中 可能由于外界条件的变更 不设想的不一致 导致出现错误的情况 如数据库连接 异常不同于常
  • C++类对象创建过程(分配空间、赋值和初始化、对象初始化顺序、虚函数表指针)

    http my oschina net alphajay blog 5029 from rss 初看到这个题目 你可能会有些疑惑 C 类对象的创建还有什么好说的 不就是调用构造函数么 实际上情况并不是想象中的那么简单 大量的细节被隐藏或者被
  • Node-RED中配置周期性执行、指定时间阶段执行、指定时间执行事件

    场景 Node RED简介与Windows上安装 启动和运行示例 Node RED简介与Windows上安装 启动和运行示例 霸道流氓气质的博客 CSDN博客 在inject节点可以设置重复触发的周期性事件 比如每两秒输出一次时间 注 博客
  • Windows系统服务器如何磁盘挂载

    桌面远程登录服务器后 服务器桌面上只有一个回收站的 我们在桌面空白处右键属性 gt 桌面 gt 自定义桌面 gt 然后把我的电脑前面的框框勾上 再然后点应用 确定 ok 回到桌面我们就能看到我的电脑了 步骤 点击我们电脑 gt 右键管理 g
  • VSCODE设置位置

    目录 设置位置 用户区 工作区 设置方法 设置编辑器 设置文件 结束 设置位置 VSCODE设置位置分为用户区和工作区 用户区 用户设置是全局的 对所有工作区和项目都有效 用户设置会存储在用户的配置文件夹中 并以settings json文
  • oceanbase 与hbase主要区别

    oceanbase支持跨表的事务 而hbase中支持跨行的事务 这是由他们的设计特别决定的 updateserver实际上是将Hbase所有ReginonServer的memtable聚合在一起 regionserver只服务一部分tabl
  • 编程tips

    一 是XOR 是不等于 if a b 和if a b 对对于聪明的编译器来说效率应该是一样的 二 与 的优先级比 高一级 表达式的结合次序取决于表达式中各种运算符的优先级 优先级从上到下依次递减 最上面具有最高的优先级 逗号操作符具有最低的
  • Spring中AOP

    1 概述 AOP 面向切面编程 将程序中的非业务代码抽取 在不修改业务代码的前提下 为其添加功能 功能增强 面向切面的编程思想底层是为目标创建一个代理对象 让代理对象调用目标类中方法 在代理对象调用时 可以额外的调用其他的方法 增强的方法