Spring framework Day21:Spring AOP 注解结合配置类示例

news2024/11/18 1:48:17

前言

Spring AOP是一种强大的面向切面编程工具,它能够帮助我们更好地处理与核心业务逻辑无关的横切关注点。通过使用注解和配置类的方式,我们可以更加简洁和灵活地实现AOP。

本文将以一个示例来介绍如何结合注解和配置类来使用Spring AOP。通过这个示例,你将了解如何使用注解来定义切点、通知和切面,并通过配置类来启用和配置AOP。

前面三章我们都是通过 xml 文件去配置,那么这章我们开始使用 Java 配置类加注解来完成案例。

注意:使用 xml 是为了让大家了解 xml 怎么去配置,现在常用的都是注解加 Java 配置类来实现。

在开始之前,请确保你已经具备了Spring框架的基础知识,并且已经正确配置了Spring环境。

接下来,我们将一步步地介绍这个示例,让我们开始吧!

一、开始学习

1、新建项目,结构如下

 2、添加 spring 依赖
 
    <!-- spring 的核心依赖 -->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.23</version>
        </dependency>
 
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.5</version>
        </dependency>
 
         <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.8</version>
        </dependency>
 
 
    </dependencies>
3、在 service 包下新建一个 UserService 类(被代理的目标类)

@Slf4j
@Service
public class UserService {

    /**
     * 目标方法,也就是需要被增强的方法
     * 因此它就是一个连接点
     * @param name
     */
    public String add(String name){
        log.info("添加用户..." + name);
        return "success";
    }

}
4、在 aspect 包下新建一个 UserAspect 切面类
@Slf4j
// 将切面纳入容器管理
@Component
/**
 * 使用 @Aspect 注解标识当前类为一个切面
 */
@Aspect
public class UserAspect {

    @Pointcut("execution(* edu.nf.ch21.service.UserService.*(..))")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void before(JoinPoint jp) {
        log.info("前置通知");
    }

    /**
     * 后置通知
     *
     * @param jp
     * @param returnVal
     */
    @AfterReturning(value = "pointcut()", returning = "returnVal")
    public void afterReturning(JoinPoint jp, Object returnVal) {
        log.info("后置通知,目标方法返回值:" + returnVal);
    }

    /**
     * 环绕通知
     *
     * @param jp
     * @return
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint jp) throws Throwable {
        log.info("环绕通知前,方法参数:" + jp.getArgs()[0]);
        Object returnVal = jp.proceed();
        log.info("环绕通知后,方法返回值:" + returnVal);
        return returnVal;
    }

    /**
     * 异常通知
     *
     * @param jp
     * @param e
     */
    @AfterThrowing(value = "pointcut()", throwing = "e")
    public void afterThrowing(JoinPoint jp, Exception e) {
        log.info("异常通知:" + e.getMessage());
    }

    /**
     * 最终通知
     * @param jp
     */
    @After("pointcut()")
    public void after(JoinPoint jp){
        log.info("最终通知");
    }

}

这个切面类定义了一个pointcut()切点方法,用于指定哪些方法需要被拦截。这里使用了execution()表达式来匹配edu.nf.ch21.service.UserService类中的所有方法。

接下来,针对这个切点方法,定义了五个通知方法:

  • before()方法是一个前置通知,在目标方法执行之前执行,并且拦截到JoinPoint参数,可以获取目标方法的信息。
  • afterReturning()方法是一个后置通知,在目标方法正常返回时执行,拦截到JoinPoint和目标方法的返回值returnVal参数。
  • around()方法是一个环绕通知,可以在目标方法执行前、执行后都做一些处理,并拦截到ProceedingJoinPoint参数,可以手动调用目标方法并获取返回值。
  • afterThrowing()方法是一个异常通知,在目标方法抛出异常时执行,拦截到JoinPointException参数。
  • after()方法是一个最终通知,在目标方法执行结束后(包括正常结束和异常结束)执行,拦截到JoinPoint参数。

 其中还使用了很多的注解,它们分别是什么意思?

  1. @Component: 这是Spring框架的注解之一,用于将类标识为一个可被Spring容器扫描和管理的组件。在这个示例中,@Component注解表示将UserAspect类作为一个切面组件纳入到Spring容器中。

  2. @Aspect: 这是AspectJ框架的注解,用于标识一个类为切面。切面是一个包含了各种通知和切点的类,用于对其他类中的方法进行拦截和增强。

  3. @Pointcut: 这是一个自定义的方法级别注解,用于定义一个切点。切点决定了哪些方法会被拦截和应用切面逻辑。在这个示例中,pointcut()方法使用了@Pointcut注解来定义切点。

  4. @Before: 这是一个前置通知注解,用于在目标方法执行之前执行某段逻辑。在这个示例中,before()方法使用了@Before注解,表示在匹配到的方法执行之前会执行before()方法中的逻辑。

  5. @AfterReturning: 这是一个后置返回通知注解,用于在目标方法正常返回时执行某段逻辑。在这个示例中,afterReturning()方法使用了@AfterReturning注解,并通过value属性指定了切点,returning属性指定了目标方法返回值的参数名,表示在匹配到的方法正常返回时会执行afterReturning()方法中的逻辑。

  6. @Around: 这是一个环绕通知注解,用于在目标方法执行前和执行后执行某段逻辑。在这个示例中,around()方法使用了@Around注解,并通过value属性指定了切点,表示在匹配到的方法执行前后会执行around()方法中的逻辑。注意,around()方法的参数类型为ProceedingJoinPoint,可以手动调用目标方法。

  7. @AfterThrowing: 这是一个异常通知注解,用于在目标方法抛出异常时执行某段逻辑。在这个示例中,afterThrowing()方法使用了@AfterThrowing注解,并通过value属性指定了切点,throwing属性指定了异常的参数名,表示在匹配到的方法抛出异常时会执行afterThrowing()方法中的逻辑。

  8. @After: 这是一个最终通知注解,用于在目标方法执行结束后执行某段逻辑,无论是否抛出异常。在这个示例中,after()方法使用了@After注解,并通过value属性指定了切点,表示在匹配到的方法执行结束后会执行after()方法中的逻辑。

总结起来,这些注解一起使用可以实现对目标方法的拦截和增强,例如在方法执行前后打印日志、记录返回值、处理异常等。

5、在 config 包下新建一个  AppConfig 配置类
@Configuration
@ComponentScan(basePackages = "edu.nf.ch21")
// 启用 AspectJ 注解处理器
// proxyTargetClass 指定为 true 表示强制使用 cglib 生成代理
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
}

这段代码是一个Spring配置类,用于配置Spring容器和启用AspectJ注解处理器。下面是对每个注解的解释:

  • @Configuration: 这是一个Spring框架的注解,用于表示该类是一个配置类。配置类通常用于定义Bean的创建和配置,以及其他的Spring配置。

  • @ComponentScan: 这是一个Spring框架的注解,用于指定要扫描的包或类的路径。在这个示例中,basePackages属性指定了要扫描的基础包路径为"edu.nf.ch21",意味着Spring容器会扫描并加载该包及其子包中的组件。

  • @EnableAspectJAutoProxy: 这是一个Spring框架的注解,用于启用AspectJ注解处理器,并开启基于AspectJ的自动代理功能。proxyTargetClass = true表示使用cglib生成代理对象而不是默认的基于接口的JDK动态代理方式。

这些注解的组合作用是将该配置类纳入Spring容器的管理,并启用AspectJ注解处理器和自动代理功能,从而实现AOP(面向切面编程)的特性。

6、测试
public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService bean = context.getBean(UserService.class);
        bean.add("qiu");
    }

}

 运行结果

使用注解开发,效率是不是很高,没错,在实际开发中注解和 Java 配置类确实是很开。也是开发中最常用的一种,当然 xml 也可以,只不过是使用 Java 配置类加注解开发会比较好看,阅读性好。大家根据自己的选择使用,推荐使用的是这种方法。

 

二、使用Spring AOP 注解结合配置类和使用 xml 有什么区别

使用Spring AOP注解和配置类与使用XML方式定义AOP有以下区别:

  1. 配置方式:使用注解的方式是通过在代码中添加注解来定义切面、切点和通知等,而使用XML方式是通过编写XML配置文件来定义AOP元素。

  2. 代码可读性:使用注解方式可以直接在Java代码中看到AOP相关的配置,使得代码更加紧凑和可读。而使用XML方式需要打开独立的XML配置文件,可能会增加代码的复杂性。

  3. 配置灵活性:使用注解方式可以更灵活地进行配置,可以直接将切面和通知应用于具体的类或方法,也可以使用通配符来匹配一组类或方法。而使用XML方式则需要在配置文件中明确指定切入点和通知的目标。

  4. IDE支持:使用注解方式可以充分利用现代IDE的代码提示和自动补全功能,提升开发效率。而使用XML方式则需要手动编写XML配置文件,可能会增加书写错误的风险。

  5. 集成和维护:使用注解方式可以更加方便地进行代码集成和版本控制,同时也更容易进行维护和重构。而使用XML方式则可能导致配置文件随着系统变得越来越庞大和难以管理。

总的来说,注解方式相对于XML方式更加简洁、灵活和方便于代码维护,但对于复杂的AOP配置或需要与第三方库进行集成的情况,XML方式可能更为适用。选择使用哪种方式还取决于个人或团队的偏好和具体的项目需求。

三、gitee 案例

案例完整地址:https://gitee.com/qiu-feng1/spring-framework.git

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1106202.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决Antd 二次封装表格的可编辑功能(editable table)不生效的问题

问题概述 使用了Antd Table组件&#xff0c;因为需要自定义的筛选功能&#xff0c;进行了二次封装。 之后加上了可编辑行功能&#xff0c;当点击编辑图标&#xff0c;发现表格并不会有任何变化。 代码&#xff1a; <Formcomponent{false}form{docInfoForm} ><CSTab…

正点原子嵌入式linux驱动开发——设备树下LED驱动

经过对设备树的学习以及驱动开发中常用的OF函数介绍&#xff0c;本篇笔记将之前的新字符设备驱动的LED&#xff0c;换成设备树形式。 设备树LED驱动原理 在之前的新字符设备驱动实验中&#xff0c;直接在驱动文件newchrled.c中定义有关寄存器物理地址&#xff0c;然后使用io_…

【前端学习】—Vue生命周期(十七)

【前端学习】—Vue生命周期&#xff08;十七&#xff09; 一、Vue生命周期 二、Vue父子组件生命周期调用顺序 三、Vue中在哪个生命周期内调用异步请求

【SpringCloud微服务项目实战-mall4cloud项目(4)】——mall4cloud-rbac

mall4cloud-rbac角色权限访问控制模块 系统架构与模块介绍系统架构rbac模型介绍 相关代码权限校验接口代码 补充 代码地址 github地址 fork自github原始项目 gitee地址 fork自gitee原始项目 系统架构与模块介绍 系统架构 从图中可以看到&#xff0c;微服务集群中&#xff0c;…

Netty系列教程之NIO基础知识

近30集的孙哥视频课程&#xff0c;看完一集整理一集来的&#xff0c;内容有点多&#xff0c;请大家放心食用~ 1. 网络通讯的演变 1.1 多线程版网络通讯 在传统的开发模式中&#xff0c;客户端发起一个 HTTP 请求的过程就是建立一个 socket 通信的过程&#xff0c;服务端在建立…

直线导轨在喷涂行业中的应用场景

直线导轨因其具有精度高、速度快、刚性强、使用寿命长等特点被广泛应用在各行各种中&#xff0c;其中&#xff0c;在喷涂行业中的应用最为广泛&#xff0c;以下是直线导轨在喷涂行业中的应用场景&#xff1a; 1、平面喷涂&#xff1a;直线导轨可以应用在各种机械加工的平面&…

将Sketch文件转化为PSD文件的简单在线工具!

设计工作不仅需要UI设计工具&#xff0c;还需要Photoshop。常见的UI设计工具Sketch与Photoshop软件不兼容。如果你想在实际工作中完成Sketch转psd&#xff0c;你需要使用其他软件进行转换。但是在转换过程中容易丢失文件&#xff0c;导致同样的工作需要重复多次才能完成&#x…

图论相关算法

一、迪杰斯特拉(Dijkstra)算法 迪杰斯特拉算法使用类似广度优先搜索的方法解决了带权图的单源最短路径问题。这是一个贪心算法。 1.核心思想 &#xff08;1&#xff09;每次选中一个点&#xff0c;这个点满足两个条件&#xff1a; 未被选过距离最短 &#xff08;2&#xf…

Gazebo仿真 【ROS: noetic】

参考链接&#xff1a;《ROS机器人开发实践》_胡春旭 目标&#xff1a; 了解如何使用URDF文件创建一个机器人模型&#xff0c;然后使用xacro文件优化该模型&#xff0c;并且放置到rvizArbotiX或Gazebo仿真环境中&#xff0c;以实现丰富的ROS功能。 4.5 Gazebo仿真环境 1&#x…

kaggle新赛:UBC卵巢癌亚型分类和异常检测大赛【图像分类】

赛题名称&#xff1a;UBC Ovarian Cancer Subtype Classification and Outlier Detection (UBC-OCEAN) 赛题链接&#xff1a;https://www.kaggle.com/competitions/UBC-OCEAN 赛题背景 卵巢癌是女性生殖系统最致命的癌症。目前&#xff0c;卵巢癌诊断依赖病理学家评估亚型。…

MySQL的自增id会用完吗?用完怎么办?

MySQL作为最常用的关系型数据库&#xff0c;无论是在应用还是在面试中都是必须掌握的技能。 目录 一、MySQL自增主键会用完吗 二、MySQL自增主键用完会怎样 1.程序员自己设置的自增主键 2.程序员没有设置自增主键&#xff0c;mysql自动创建row_id 三、mysql中还有哪些自增…

IF: 22.1, 中科院1区TOP刊被剔除WOS (10月SCI/SSCI目录已更新)~

2023年10月17日&#xff0c;科睿唯安更新了Web of Science核心期刊目录。 此次更新后SCIE期刊目录共包含9485本期刊&#xff0c;SSCI期刊目录共包含3551本期刊。此次SCIE & SSCI期刊目录更新&#xff0c;与上次更新&#xff08;2023年9月&#xff09;相比&#xff0c;共有7…

电子期刊制作宝典,让你成为专业行家

电子期刊作为一种新兴的媒体形式&#xff0c;越来越受到人们的喜爱。它不仅方便快捷&#xff0c;而且可以随时随地阅读&#xff0c;不受时间和空间的限制。那么&#xff0c;如何制作一份高质量的电子期刊呢&#xff1f; 1.首先打开FLBOOK电子杂志平台 2.然后点击模板选择电子期…

springBoot--web开发--WebMvcAutoConfiguration原理

WebMvcAutoConfiguration原理 自动配置类的生效条件hiddenHttpMethodFilter和formContentFilter的作用WebMvcConfigurer的作用 自动配置类的生效条件 点击ctarln 搜索类WebMvcAutoConfiguration hiddenHttpMethodFilter和formContentFilter的作用 hiddenHttpMethodFilter&am…

CLIP模型原理

CLIP模型 CLIP(Contrastive Language-Image Pre-Training) 模型是 OpenAI 在 2021 年初发布的用于匹配图像和文本的预训练神经网络模型&#xff0c;是近年来在多模态研究领域的经典之作。OpenAI 收集了 4 亿对图像文本对&#xff08;一张图像和它对应的文本描述&#xff09;&a…

UPS设备的最新管理方法,简单高效!

随着信息技术的快速发展&#xff0c;UPS监控系统变得至关重要。系统用于监视、管理和维护机房中的UPS设备&#xff0c;以确保稳定的电力供应&#xff0c;保护敏感的电子设备和数据中心运营。 UPS监控系统提供了对电力系统的关键可见性&#xff0c;使运维团队能够预测和解决潜在…

家政系统预约小程序具备哪些功能?

预约家政小程序有这么大的市场需求加上这么多的好处&#xff0c;相信未来发展前景不错。也必将吸引很多商家投资者着手开发属于自己的上门家政APP小程序软件&#xff0c;在实际的开发过程中需要具备哪些功能呢&#xff1f; 一、用户端功能&#xff1a; 1. 用户注册登录&#x…

绕过防火墙

1.pikuchu靶场 位置 该文件 然后找到install 文件 初始化 创建 就ok了 安全狗搭建 bug解决 进入apache目录 命令 安全狗安装 重启web服务 绕过 前端 绕过 waf 阻拦 脏数据 成功 二.yakit 中国版的bp

源码编译安装部署lnmp

源码编译安装部署lnmp 文章目录 源码编译安装部署lnmp1.简介&#xff1a;2.环境说明&#xff1a;3.部署前的准备工作4.安装nginx4.1.进入官网拉取nginx源码包4.2.通过IP地址访问nginx的web页面 5.安装mysql5.1.安装依赖包5.2.创建用户和组5.3.下载源码包并解压到/usr/local/5.4…

在数组中合并相同id数据,并且数据中某一字段不一致也统一合并进去

封装的合并的函数 function formateArray(data:any){// ts-ignorelet res data.reduce((ac,a) > {// ts-ignorelet index ac.findIndex(x > x.id a.id);index -1 ? ac.push({...a}) : ac[index] {...ac[index],...a};return ac;},[])return res;}使用 allData 原始…