Spring Boot中的AOP编程实践

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Spring Boot中的AOP编程实践

一、AOP基本概念


在深入实践之前,首先了解几个AOP的核心概念:

  1. 切面(Aspect):封装横切关注点的模块。
  2. 连接点(Join Point):程序执行过程中可以插入切面的特定点。
  3. 通知(Advice):切面在连接点执行的代码。
  4. 切点(Pointcut):定义连接点的集合。
  5. 目标对象(Target Object):包含连接点的对象。
  6. 织入(Weaving):将切面应用到目标对象的过程。


二、Spring Boot中使用AOP


接下来,我们通过一个简单的示例展示如何在Spring Boot中使用AOP来记录方法执行时间。


1. 创建Spring Boot项目


首先,使用Spring Initializr创建一个新的Spring Boot项目,添加spring-boot-starter-aop依赖。


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


2. 定义业务服务


创建一个简单的业务服务类cn.juwatech.service.DemoService,包含一个模拟耗时操作的方法。


package cn.juwatech.service;
import org.springframework.stereotype.Service;
@Service
public class DemoService {
    public void performTask() {
        try {
            // 模拟耗时操作
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Task performed.");
    }
}


3. 定义切面类


创建一个切面类cn.juwatech.aspect.LoggingAspect,用于记录方法的执行时间。


package cn.juwatech.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
    @Around("execution(* cn.juwatech.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long executionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        return proceed;
    }
}


4. 配置AOP


在Spring Boot项目中,AOP自动配置通常已经启用。如果没有特殊需求,不需要额外配置。但如果需要自定义配置,可以在application.properties中进行设置。


# 启用AOP自动代理
spring.aop.auto=true
# 启用CGLIB代理
spring.aop.proxy-target-class=true


5. 编写测试


创建一个简单的测试类cn.juwatech.Application,运行DemoServiceperformTask方法,观察日志输出。


package cn.juwatech;
import cn.juwatech.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
    @Autowired
    private DemoService demoService;
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    @Override
    public void run(String... args) throws Exception {
        demoService.performTask();
    }
}


运行应用程序,可以看到控制台输出如下日志:


execution(void cn.juwatech.service.DemoService.performTask()) executed in 2003ms
Task performed.


三、更多AOP用例


除了记录方法执行时间,AOP还可以应用于以下场景:

  1. 日志记录:自动记录方法调用的输入输出参数及返回值。
  2. 事务管理:在方法执行前后自动开启和关闭事务。
  3. 权限控制:在方法执行前进行权限校验。
  4. 异常处理:统一处理方法抛出的异常。


1. 日志记录示例


package cn.juwatech.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
    @AfterReturning(pointcut = "execution(* cn.juwatech.service.*.*(..))", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println(joinPoint.getSignature() + " returned with value " + result);
    }
}


2. 事务管理示例


Spring Boot已经提供了@Transactional注解,可以直接使用。


package cn.juwatech.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DemoService {
    @Transactional
    public void performTransactionalTask() {
        // 事务性操作
    }
}


3. 权限控制示例


package cn.juwatech.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class SecurityAspect {
    @Before("execution(* cn.juwatech.service.*.*(..))")
    public void checkPermission() {
        // 权限校验逻辑
    }
}


4. 异常处理示例


package cn.juwatech.aspect;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class ExceptionHandlingAspect {
    @AfterThrowing(pointcut = "execution(* cn.juwatech.service.*.*(..))", throwing = "ex")
    public void handleException(Exception ex) {
        // 异常处理逻辑
        System.err.println("Exception caught: " + ex.getMessage());
    }
}


总结


通过本文的介绍,我们展示了如何在Spring  Boot中进行AOP编程实践。我们从AOP的基本概念入手,通过一个简单的示例展示了如何使用Spring  AOP记录方法的执行时间。随后,我们扩展介绍了更多AOP的应用场景,如日志记录、事务管理、权限控制和异常处理。AOP的强大之处在于它能够帮助我们将横切关注点与业务逻辑分离,从而提高代码的可维护性和可复用性。希望这些内容对大家有所帮助,能够在实际项目中应用并优化代码结构。

相关实践学习
日志服务之数据清洗与入湖
本教程介绍如何使用日志服务接入NGINX模拟数据,通过数据加工对数据进行清洗并归档至OSS中进行存储。
相关文章
|
3天前
|
XML 监控 Java
Java中的AOP编程:AspectJ与Spring AOP的应用
Java中的AOP编程:AspectJ与Spring AOP的应用
|
2天前
|
容器
springboot-自定义注解拦截ip aop和ioc
springboot-自定义注解拦截ip aop和ioc
|
2天前
|
Java Spring
Spring AOP(面向切面编程)详解
Spring AOP(面向切面编程)详解
|
2天前
|
开发框架 监控 Java
Spring Boot中的反应式编程最佳实践
Spring Boot中的反应式编程最佳实践
|
3天前
|
XML 监控 Java
Spring框架的核心原理与应用实践
Spring框架的核心原理与应用实践
|
3天前
|
Java 测试技术 数据安全/隐私保护
Spring Boot中的AOP编程实践
Spring Boot中的AOP编程实践
|
21天前
|
Java Maven 数据安全/隐私保护
详解 Java AOP:面向方面编程的核心概念与 Spring 实现
详解 Java AOP:面向方面编程的核心概念与 Spring 实现
26 1
|
8天前
|
前端开发 Java 数据库
浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
|
8天前
|
XML Java 数据格式
技术好文:Spring基础篇——AOP切面编程
技术好文:Spring基础篇——AOP切面编程
|
2月前
|
XML 监控 安全
Spring特性之一——AOP面向切面编程
Spring特性之一——AOP面向切面编程
42 1