SpringBoot中的Aop用法示例详解

Spring Boot 中的 AOP 用法示例详解

什么是 AOP?

AOP(Aspect Oriented Programming)即面向切面编程,是一种常见的编程范式。AOP 可以将一些常用的横切逻辑(比如日志、安全检查等)模块化,使得代码更具可读性、可维护性、可重用性。

Spring Boot 中的 AOP

Spring Boot 框架提供了很好的 AOP 实现机制,让我们可以轻松地在应用程序中使用 AOP。

AOP 术语

在了解 Spring Boot 中的 AOP 用法之前,先来介绍一些 AOP 的基本术语:

  • Join point(连接点):程序执行过程中的一个点。通常表示一个方法的执行时机。
  • Pointcut(切点):一组匹配方法的连接点。
  • Advice(通知):在切点执行前、后或环绕时要执行的方法。
  • Aspect(切面):包含切点和与之对应的通知的模块。
  • Weaving(织入):将切面代码插入到目标程序的过程。

Spring Boot 中如何配置 AOP?

首先,我们需要在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

其次,我们需要在配置类中添加 @EnableAspectJAutoProxy 注解,以启用 Spring Boot 的 AOP 自动代理功能。

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
    // 配置类的其他内容
}

然后,我们需要创建一个切面类(Aspect),并在其中定义一个切点(Pointcut)和一个通知(Advice)。

@Aspect
public class LoggingAspect {

    @Pointcut("within(com.example.demo.service..*)")
    public void serviceLayer() {}

    @Before("serviceLayer()")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("调用了 " + joinPoint.getSignature().getName() + " 方法");
    }
}

在上述代码中,我们定义了一个名为 LoggingAspect 的切面类,其中包括一个名为 serviceLayer() 的切点和一个名为 logBefore() 的通知。

切点表达式 "within(com.example.demo.service..*)" 表示匹配 com.example.demo.service 包下的所有方法。

通知方法 logBefore() 使用 @Before 注解进行标记,表示在 serviceLayer() 切点所匹配的方法执行前,会先执行 logBefore() 这个方法。

最后,我们需要在 AOP 配置类中注册切面类。

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

    @Bean
    public LoggingAspect loggingAspect() {
        return new LoggingAspect();
    }
}

现在,在调用 com.example.demo.service 包下的任何方法时,都会执行 logBefore() 方法,并输出调用方法的名称。

示例一:在 Spring Boot Web 应用中使用 AOP 记录日志

@RestController
public class HelloController {

    @GetMapping("/")
    public String hello() {
        return "Hello, World!";
    }
}

在上述代码中,我们定义了一个名为 HelloController 的 RESTful API 控制器,并在其中定义一个名为 hello() 的方法。现在,我们希望在该方法执行前、后记录一些日志信息。

首先,我们需要创建一个切面类(Aspect),并在其中定义一个切点(Pointcut),如下所示:

@Aspect
@Component
public class LoggingAspect {

    @Pointcut("execution(* com.example.demo.controller..*(..))")
    public void controllerLayer() {}

    @Around("controllerLayer()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("调用了 " + joinPoint.getSignature().getName() + " 方法");
        long startTime = System.currentTimeMillis();

        Object result = joinPoint.proceed();

        long endTime = System.currentTimeMillis();
        System.out.println("该方法执行时间为 " + (endTime - startTime) + " 毫秒");

        return result;
    }
}

在上述代码中,我们定义了一个名为 LoggingAspect 的切面类,并在其中定义了一个名为 controllerLayer() 的切点和一个名为 logAround() 的通知。

切点表达式 "execution(* com.example.demo.controller..*(..))" 表示匹配 com.example.demo.controller 包及其子包中的所有方法。

通知方法 logAround() 使用 @Around 注解进行标记,表示在切点所匹配的方法执行前、后、环绕时都会执行该方法。

在通知方法 logAround() 中,我们首先记录了方法的调用名称,接着记录了方法的执行时间。

最后,我们需要在 AOP 配置类中注册切面类。

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.example.demo")
public class AppConfig {

    @Bean
    public LoggingAspect loggingAspect() {
        return new LoggingAspect();
    }
}

现在,在调用 HelloControllerhello() 方法时,都会执行 logAround() 方法,并输出调用方法的名称和执行时间。

示例二:在 Spring Boot 中使用 AOP 实现事务管理

@Service
@Transactional
public class UserServiceImpl implements UserService {
    // userServiceImpl 的实现逻辑
}

在上述代码中,我们定义了一个名为 UserServiceImpl 的业务逻辑类,并在其中使用 @Transactional 注解启用了事务管理功能。现在,我们希望在该类的方法执行前、后记录一些日志信息。

首先,我们需要创建一个切面类(Aspect),并在其中定义一个切点(Pointcut),如下所示:

@Aspect
@Component
public class LoggingAspect {

    @Pointcut("execution(* com.example.demo.service.impl..*(..))")
    public void serviceLayer() {}

    @Around("serviceLayer()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("调用了 " + joinPoint.getSignature().getName() + " 方法");
        long startTime = System.currentTimeMillis();

        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            System.out.println("发生异常:" + e.getMessage());
            throw e;
        }

        long endTime = System.currentTimeMillis();
        System.out.println("该方法执行时间为 " + (endTime - startTime) + " 毫秒");

        return result;
    }
}

在上述代码中,我们定义了一个名为 LoggingAspect 的切面类,并在其中定义了一个名为 serviceLayer() 的切点和一个名为 logAround() 的通知。

切点表达式 "execution(* com.example.demo.service.impl..*(..))" 表示匹配 com.example.demo.service.impl 包及其子包中的所有方法。

通知方法 logAround() 使用 @Around 注解进行标记,表示在切点所匹配的方法执行前、后、环绕时都会执行该方法。

在通知方法 logAround() 中,我们首先记录了方法的调用名称,接着记录了方法的执行时间。

注意:在 logAround() 方法中,如果业务逻辑方法执行过程中发生了异常,需要将异常抛出,以便事务能够正常回滚。

最后,我们需要在 AOP 配置类中注册切面类。

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.example.demo")
public class AppConfig {

    @Bean
    public LoggingAspect loggingAspect() {
        return new LoggingAspect();
    }
}

现在,在调用 com.example.demo.service.impl 包下的任何方法时,都会执行 logAround() 方法,并输出调用方法的名称和执行时间。如果发生异常,也会记录异常信息并将其抛出,以便事务能够正常回滚。

结论

在本文中,我们介绍了 AOP 的基础概念以及 Spring Boot 中如何使用 AOP 实现日志记录和事务管理。这些示例可以帮助你更好地理解和使用 Spring Boot 的 AOP 机制。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot中的Aop用法示例详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java中网络IO的实现方式(BIO、NIO、AIO)介绍

    Java中网络IO的实现方式主要有BIO、NIO、AIO三种。下面分别进行介绍。 BIO BIO即Blocking IO,阻塞式IO,是一种传输方式。BIO的特点是同步阻塞,也就是说,客户端请求到来后,服务器必须处理完该请求才能执行下一步操作,高并发下无法满足需求。使用BIO方式,可以使用Socket和ServerSocket类进行通信。 下面是一个BIO的…

    Java 2023年5月19日
    00
  • Spring boot实现应用打包部署的示例

    下面我将为你详细介绍Spring Boot实现应用打包部署的完整攻略。 什么是Spring Boot Spring Boot是Spring框架的一种扩展,其主要目的是简化Spring应用(特别是Spring MVC)的搭建和开发流程。Spring Boot以约定优于配置的方式来实现自动化的Spring应用搭建,大部分的Spring Boot应用只需要很少的配…

    Java 2023年5月15日
    00
  • Java的Hibernate框架中Criteria查询使用的实例讲解

    Java的Hibernate框架中Criteria查询使用的实例讲解 Hibernate是一个强大的ORM(对象关系映射)框架,在Hibernate中,Criteria API是一个使用简单的标准API,它提供了在不检查语法的情况下动态构建查询的功能。本文将对Java的Hibernate框架中Criteria查询使用的实例进行讲解。 Criteria查询的基…

    Java 2023年5月19日
    00
  • 一文探究ArrayBlockQueue函数及应用场景

    一文探究ArrayBlockingQueue函数及应用场景 介绍 ArrayBlockingQueue是Java中的一个阻塞队列实现类,它是一个支持在队列的两端插入和删除元素的线程安全队列。它的大小是有限的,当队列已满时,插入操作会阻塞线程,直到队列有空闲空间;当队列为空时,获取操作会阻塞线程,直到队列有可用元素。 使用方法 创建ArrayBlockingQ…

    Java 2023年5月26日
    00
  • kafka并发写大消息异常TimeoutException排查记录

    针对“kafka并发写大消息异常TimeoutException排查记录”这个问题,我给大家提供下面的攻略: 问题描述 Kafka是一款分布式消息系统,支持高并发、高吞吐量的数据处理场景。但是,有时候在并发写入大消息时,可能会出现TimeoutException异常,导致消息写入失败,引起系统的异常。那么如何排查和解决这个问题呢? 问题原因分析 Timeou…

    Java 2023年5月20日
    00
  • jsp实现Servlet文件下载的方法

    实现Servlet文件下载可以通过JSP页面的form表单提交或通过Servlet的输出流方式进行,下面分别进行讲解。 通过JSP页面的form表单提交下载文件 在JSP页面中添加form表单,设置action为需要下载文件的Servlet路径。 “`html 下载文件 “` 其中,fileName为要下载文件的文件名。 在Servlet中获取要下载的文…

    Java 2023年6月15日
    00
  • 使用Java打印数字组成的魔方阵及字符组成的钻石图形

    下面我详细讲解一下“使用Java打印数字组成的魔方阵及字符组成的钻石图形”的完整攻略。 打印数字组成的魔方阵 思路 魔方阵是由 $n^2$ 个数字组成的方阵,其中每一行、每一列、每一条对角线上的数字之和都相等。我们可以使用以下的算法来生成 $n \times n$ 的魔方阵: 将数字 1 放在第一行的中间列。 依次将后续的数字放入前一个数字的右上角(如果已经…

    Java 2023年5月26日
    00
  • Java之Spring Boot创建和使用

    Java之Spring Boot创建和使用 Spring Boot是一个基于Spring Framework的快速应用开发框架。它可以快速创建、运行Spring应用,提供自动配置、内嵌服务器等特性,可以让我们更加专注于业务的实现,而不用花费大量时间在Spring应用的配置上。 安装和配置 安装和配置Spring Boot非常简单,只需要以下几个步骤: 下载最…

    Java 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部