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日

相关文章

  • SpringMVC MVC架构原理及实现方法详解

    以下是关于“SpringMVC MVC架构原理及实现方法详解”的完整攻略,其中包含两个示例。 SpringMVC MVC架构原理及实现方法详解 SpringMVC是一个基于MVC模式的Web框架,它提供了一种灵活、高效的方式来开发Web应用程序。在SpringMVC中,MVC是如何实现的?下面我们来详细讲解。 MVC架构原理 MVC是Model-View-C…

    Java 2023年5月16日
    00
  • JSP中使用JavaScript动态插入删除输入框实现代码

    下面是“JSP中使用JavaScript动态插入删除输入框实现代码”的完整攻略。 简介 JSP是一种动态网页技术,而JavaScript是一种脚本语言,两者可以结合使用,达到更好的用户交互效果。此次攻略将详细讲解如何在JSP页面中使用JavaScript实现动态插入删除输入框的功能。 实现步骤 实现插入输入框功能 在JSP页面中添加一个按钮,用于触发插入输入…

    Java 2023年6月15日
    00
  • spring mvc中的@PathVariable动态参数详解

    在Spring MVC中,@PathVariable注解用于从URL中提取动态参数。本文将详细讲解@PathVariable动态参数的使用方法,并提供两个示例说明。 步骤一:创建Controller 我们可以创建一个Controller类,并使用@RequestMapping注解来将请求URL映射到方法上。下面是一个示例: @Controller @Requ…

    Java 2023年5月18日
    00
  • JSP的setProperty的使用方法

    下面是详细讲解“JSP的setProperty的使用方法”的完整攻略。 JSP的setProperty的使用方法 在JSP页面中,可以通过使用<jsp:useBean>标签实例化JavaBean,并使用<jsp:getProperty>和<jsp:setProperty>标签来访问和设置JavaBean的属性。本文将介绍如…

    Java 2023年6月15日
    00
  • windows下vscode+vs2019开发JNI的示例

    下面是“Windows下VSCode+VS2019开发JNI的示例”的完整攻略。 背景介绍 Java Native Interface(JNI)是Java和本地C/C++代码交互的一种极其灵活的方式。JNI允许Java应用程序在其运行过程中调用本地C/C++应用程序,并让本地应用程序调用Java应用程序。该过程包括使用Java编写代码,编译Java代码生成J…

    Java 2023年5月26日
    00
  • Java上传文件错误java.lang.NoSuchMethodException的解决办法

    Java上传文件时,可能会出现java.lang.NoSuchMethodException错误,这通常是由于使用了错误的MultipartResolver解析器所致。下面是解决此问题的完整攻略: 1. 确认Spring版本 首先,确认你的Spring版本是否能够支持MultipartResolver解析器。MultipartResolver解析器的支持是从…

    Java 2023年5月25日
    00
  • Spring零基础入门WebFlux响应式编程

    Spring零基础入门WebFlux响应式编程攻略 什么是WebFlux? WebFlux是Spring框架5.0版本引入的新特性,它是基于响应式编程模型的Web框架,具有高可扩展性、高并发性等优势。 必备技能要求 在学习WebFlux前,需要掌握以下技能: Spring基础知识,如IoC/DI、AOP等概念 Java 8的Lambda表达式和Stream …

    Java 2023年5月19日
    00
  • Spring Security 自定义授权服务器实践记录

    Spring Security 自定义授权服务器实践记录 本文将详细讲解如何使用Spring Security自定义授权服务器,并提供两个示例说明。 前置条件 在开始学习本文前,需要准备以下环境: JDK1.8或以上版本 Maven 3.0或以上版本 Spring Boot 2.0或以上版本 配置依赖 首先,需要在pom.xml中添加以下依赖: <de…

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