当前位置: 首页 > article >正文

Spring Boot2.x教程:(九)AOP基本概念与示例

AOP基本概念与示例

  • 1、概述
  • 2、概念
    • 2.1、什么是连接点
    • 2.2、什么是切点
    • 2.3、切点的作用
    • 2.4、切点不能单独执行
    • 2.5、什么是通知
    • 2.6、通知的作用
    • 2.7、切点与通知的关系
    • 2.8、连接点与切点的关系
    • 2.9、什么是切面
    • 2.10、切面的组成
    • 2.11、切面的作用
    • 2.12 织入
  • 3、示例演示
    • 3.1、程序的执行流程
  • 4、总结

大家好,我是欧阳方超,可以扫描下方二维码关注我的公众号“欧阳方超”,后续内容将在公众号首发。 在这里插入图片描述

在这里插入图片描述

1、概述

Aspect-Oriented Programming (AOP) 是一种编程范式,旨在将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来。Spring Boot 提供了强大的 AOP 支持,使开发者能够轻松实现这些功能。本文将探讨 AOP 的基本机制及其在 Spring Boot 中的应用。

2、概念

在面向切面编程中(AOP),连接点(Joinpoint)、切点(Pointcut)、通知、切面、织入是两个关键概念,它们共同构成了AOP的核心机制。

2.1、什么是连接点

连接点(Joinpoint)是程序执行中的一个具体时刻,比如方法调用前、方法调用后、方法抛出异常时等。在Spring AOP中,连接点主要指的是方法的执行。想象你开车经过一条高速公路,这条高速公路有多个出口,每个出口都可以视为一个连接点,虽然所有这些出口都是可以选择的,但你只会选择一个特定的出口来驶离高速,这就像在程序中,所有满足条件的时机都是连接点,但你只会在特定的连接点上应用通知。

2.2、什么是切点

切点(Pointcut)是AOP中用于定义在哪些连接点(Joinpoint)上应用通知的机制。它通过切点表达式来匹配特定的方法或连接点。举例说明换一下,

@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")

如上定义了一个切点,它可以匹配所有被@GetMapping注解修饰的方法。

2.3、切点的作用

切点用户指定哪些方法或连接点需要被增强,通过不同的表达式,开发者可以灵活选择需要拦截的方法。

2.4、切点不能单独执行

注意,切点是不能单独执行的,这与它的设计目的有关,切点只是用于匹配连接点的工具,它的设计目的是为了与通知结合使用。只有当切点匹配到某个连接点时,相应的通知才会被执行,从而实现具体任务。

2.5、什么是通知

通知(Advice)是与切点关联的实际执行逻辑,它定义了在特定连接点上要执行的操作。AOP有多种类型的通知,包括:
前置通知(@Before注解):在目标方法执行之前执行。
后置通知(@After注解):在目标方法执行之后执行。
环绕通知(@Around注解):在目标方法执行之前和之后都可以执行自定义逻辑。

2.6、通知的作用

增强功能:通知可以用来实现日志记录、性能监控、权限检查等横切关注点。
代码解耦:通过将横切关注点与业务逻辑分离,提高了代码的可维护性和科扩展性。

2.7、切点与通知的关系

切点与通知是相辅相成的:
依赖关系:切点本身并不包括任何执行逻辑,它只是一个匹配规则,没有通知,切点无法触发任何操作。
结合使用:通常情况下,开发者会定义多个切点和相应的通知,以实现灵活和可重用的横切关注点处理。

2.8、连接点与切点的关系

切点是用于定义哪些连接点需要被增强的表达式。它可以看作是从众多连接点中筛选出特定的一部分。例如,如果你只想在某个特定的方法调用前执行一些逻辑,你就会定义各一个切点来匹配那个方法。

2.9、什么是切面

切面是一个模块化的单元,专门用于处理那些与业务逻辑无关但又在多个地方需要的功能,比如日志记录、事务管理、安全控制,通过将这些功能抽象为切面,开发者可以将他们从核心业务逻辑中分离出来,从而提高代码的可维护性和清晰度。

2.10、切面的组成

切面通常由两个主要部分组成:
切点(Pointcut):定义在哪些连接点(如方法调用)上应用通知。切点通过表达式来描述,例如,可以匹配特定包中的所有方法。
通知(Advice):在切点匹配到的连接点上执行的具体代码。

2.11、切面的作用

解耦:通过将横切关注点与业务逻辑分离,切面使得代码更加模块化;
复用:同一切面可以在多个地方被重用,而不需要重写代码;
集中管理:所有横切关注点的处理逻辑集中在切面中,便于统一管理和修改。

2.12 织入

织入(Weaving)是将切面应用到目标对象的过程,可以在编译期、类加载期或运行期进行。在 Spring AOP 中,通常使用动态代理来实现织入。

3、示例演示

只看理论未免显得有些乏味,下面结合示例来体会一下。
在Spring Boot项目中添加以下依赖:

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

定义一个UserService类:

package com.xxx.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void addUser(String name) {
        System.out.println("User " + name + " added.");
    }
}

定义切面:

package com.xxx.service.component;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    @Pointcut("execution(* com.xxx.service.UserService.*(..))")
    public void pointcut() {

    }
    @Before("pointcut()")
    public void logBefore(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        System.out.println("A method in UserService is about to be called.");
    }
}

然后再定义Controller:

package com.xxx.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/log")
public class LogController {

    @Autowired
    private UserService userService;

    @RequestMapping("/test")
    public void test() {
        userService.addUser("Peter");
    }
}

3.1、程序的执行流程

当请求接口/log/test时,控制器方法内部会调用userService.addUser(name), 此时Spring AOP会检查是否有与该方法相关的切点。在上面的示例中,切面LoggingAspect定义了一个切点(@Pointcut(“execution(* com.xxx.service.UserService.*(…))”)),这个切点匹配了UserService类中的所有方法,因此addUser()方法的切点匹配成功。切点匹配成功后,Spring AOP将执行与该切点关联的前置通知,在这里会执行logBefore()方法,由于传入了JoinPoint参数,可以获取到被调用方法的信息。此时控制台将输出:

A method in UserService is about to be called: addUser

前置通知执行完毕后,控制器方法继续执行,调用UserService.addUser()方法。
注意,在AOP中,切点(Pointcut)并不是绝对必要的,虽然他们通常用于定义在哪些连接点上应用通知,确实可以在没有显式定义切点的方法上直接使用通知,所以上面发的例子中切面类也可以这样写:

package com.xxx.service.component;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.xxx.service.UserService.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        System.out.println("A method in UserService is about to be called.");
    }
}

4、总结

AOP 是一种强大的编程范式,通过将横切关注点与业务逻辑分离,提高了代码的可维护性和可扩展性。Spring Boot 提供了便捷的 AOP 支持,使得开发者能够轻松实现日志记录、事务管理等功能。通过理解切点、通知、连接点和织入等基本概念,开发者可以更有效地利用 AOP 来优化应用程序架构。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。


http://www.kler.cn/a/369579.html

相关文章:

  • 人工智能:未来生活与工作的全新蓝图
  • Spring Boot植物健康系统:智慧农业的新篇章
  • PHP中防SQL注入方法
  • CSS实现回到顶部且平滑过渡
  • 如何找到适合的工程管理系统?9款对比
  • 环回地址和本地地址有什么区别
  • ssm002学院党员管理系统(论文+源码)_kaic
  • Matlab 车牌识别技术
  • 简化开发流程 低代码技术优势全解析
  • Gateway 统一网关
  • 微信小程序生成海报 / 两张图片合并生成一张
  • 【UE5】通过程序化网格体组件实现剖切功能
  • 开源生活-分布式管理
  • EasyExcel文件导入与导出
  • stp生成树协议(思科)
  • 如何对pdf文件进行加密?pdf文件加密全攻略与深度解析(5个方法)
  • 前端测试工具详解
  • 【CUDA代码实践03】m维网格n维线程块对二维矩阵的索引
  • 本地Docker部署开源WAF雷池并实现异地远程登录管理界面
  • FPM383C指纹模块超详解 附驱动
  • MPP音视频总结
  • Matlab 疲劳驾驶检测
  • 麒麟V10、UOS系统实现在线合并多个Word文件
  • MySQL 之 索引
  • Claude Financial Data Analyst:基于Claude的金融数据分析工具!免费开源!
  • 关于git上传文件冲突