SpringBoot中的Aop用法示例详解

yizhihongxing

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实现的对称加密算法3DES定义与用法示例

    Java实现的对称加密算法3DES定义与用法示例 1. 什么是3DES 3DES(Triple DES)是一种对称加密算法,常用于数据加密、数字签名等场景。它是DES(Data Encryption Standard)算法的增强版,采取3次DES步骤进行加密,因此也被称为TDEA(Triple Data Encryption Algorithm)。 3DES…

    Java 2023年5月18日
    00
  • 新手入门Jvm–jvm概览

    新手入门Jvm–JVM概览 什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,是Java程序运行的环境。Java程序在运行时,首先由Java编译器编译成字节码(bytecode),然后由JVM解释执行字节码。JVM的主要功能是解释执行字节码,并在运行时提供一系列的服务(如垃圾回收、动态加载、异常处理)。JVM是一个相对…

    Java 2023年5月19日
    00
  • Java序列化常见实现方法代码实例

    Java序列化常见实现方法代码实例 Java序列化是将Java对象转化为字节流的过程,方便进行Java对象在网络中的传输或者持久化储存。本文将介绍Java序列化的常见实现方法以及代码实例。 Java序列化实现方法 Serializable接口 Java的原生序列化实现采用Serializable接口,它是Java提供的一个标记接口,将一个类实现Seriali…

    Java 2023年5月23日
    00
  • java实现文件保存到本地的方法

    Java 实现文件保存到本地的方法可以通过以下步骤来实现。 第一步:准备保存文件的本地目录 在 Java 代码中,我们需要提前准备好一个本地保存文件的目录,可以使用 File 类来生成目录,示例代码如下: File directory = new File("D:/files"); if(!directory.exists()){ dir…

    Java 2023年5月20日
    00
  • Java后端长时间无操作自动退出的实现方式

    实现Java后端长时间无操作自动退出,主要需要使用Java的定时器和线程等相关技术。 以下是实现Java后端长时间无操作自动退出的完整攻略: 第一步:设置最大空闲时间和定时器 首先,我们需要设置一个最大空闲时间,当用户最后一次请求后,超过了该时间,就会被认为是无操作状态。例如,我们设置最大空闲时间为10分钟。 接下来,我们需要使用Java的定时器,定时器会在…

    Java 2023年5月20日
    00
  • JSP模板应用指南(上)

    JSP模板应用指南(上)完整攻略 什么是JSP模板 JSP模板即Java Server Pages的模板,是一种基于Java技术的Web开发技术。JSP模板将HTML文档和Java代码结合起来,通过JSP引擎最终生成一个可执行的Servlet程序。 JSP模板的特点 便于开发和维护 不需要额外学习其他的模板语言 实现数据和功能的封装 支持高级特性 JSP模板…

    Java 2023年6月15日
    00
  • JS代码实现table数据分页效果

    下面是JS代码实现table数据分页的完整攻略。 1. 为什么需要table数据分页 当我们在网页上展示大量数据的时候,如果直接呈现所有数据,会导致页面太长,用户体验不佳,同时会严重影响页面的加载速度和用户体验。因此,通常需要使用table数据分页的方式,将数据分成多页,让用户能够快速地定位到所需要的数据。 2. 如何实现table数据分页 实现table数…

    Java 2023年6月15日
    00
  • Maven仓库分类的优先级

    当使用 Maven 构建项目时,Maven 会从一系列仓库中查找项目的依赖。 Maven 仓库分类的优先级体现在 Maven 会按照一定顺序去仓库中查找依赖。在 Maven 中,仓库可以分为以下几类,优先级由高到低排列: 本地仓库 (Local Repository) 中央仓库 (Central Repository) 远程仓库 (Remote Reposi…

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