AOP面向切面编程

定义:看看就得了===================================

面向方面编程(AOP,Aspect-Oriented Programming) 是一种编程范式,旨在通过分离横切关注点来提高程序的模块化。横切关注点是指那些影响多个模块的功能,例如日志记录、安全检查、事务管理等。AOP 允许开发人员将这些横切关注点抽取到独立的模块(称为切面),从而使核心业务逻辑更加简洁和专注。

使用场景:========================================

简单概括就是在对原模块代码无侵入的同时做功能增强:以下是常见使用场景:

1.日志记录:可以记录某些模块的方法的调用信息,参数,返回值,执行时间等等,然后可以存到数据库,这样就可以监控这个方法

2.事务管理:实际上@Transactional就是这样实现的

3.安全检查:我要求使用某些模块时要验证用户的身份信息,我都可以指定对这些执行执行aop验证用户身份信息的逻辑

4.缓存管理:实际上@Cachaeble就是这样实现的

5.异常处理:如果想捕获某些模块中的异常并处理,就可以使用aop

说着说着感觉说的功能好像过滤器拦截器都能实现,看看区别:

  • AOP

    • 应用层次:方法级别。
    • 优点
      • 适用于业务逻辑层的横切关注点,能够精细地控制方法的前后处理。
      • 提供了强大的切面功能,可以独立于业务逻辑代码进行管理。
    • 缺点
      • 需要学习和理解 AOP 的概念和机制。
      • 对于全局性的请求和响应处理不如过滤器方便。
  • 拦截器

    • 应用层次:框架级别,一般在处理 HTTP 请求的过程中拦截。
    • ​​​​​​​优点
      • 可以在处理器执行前、执行后以及请求完成后进行拦截。
      • 能够访问和修改请求和响应对象,适用于控制器层的任务。
    • 缺点
      • 粒度不如 AOP 细,无法精确到业务方法的前后。
      • 主要用于控制器层,无法直接作用于业务逻辑层。
  • 过滤器

    • 应用层次:Servlet 容器级别,主要在 HTTP 请求和响应处理的前后进行过滤。
    • 优点
      • 适用于全局性的预处理和后处理。
      • 对所有请求和响应生效,不局限于特定的控制器或方法。
    • 缺点
      • 粒度较粗,无法精确到特定的方法级别。
      • 不适合处理业务逻辑层的横切关注点。

使用方式:下面以记录方法执行时间为例==================

1.引入依赖

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

 2.比如我们要记录UserService类中所有方法的执行时间(这里是我们要增强的业务)

package com.example.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public void addUser(String username) {
        System.out.println("Adding user: " + username);
        // 模拟方法执行时间
        try {
            Thread.sleep(200); // 睡眠 200 毫秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void deleteUser(String username) {
        System.out.println("Deleting user: " + username);
        // 模拟方法执行时间
        try {
            Thread.sleep(300); // 睡眠 300 毫秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3.定义切面类

package com.example.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 ExecutionTimeAspect {
    
    //定义切入点表达式,也就是要拦截哪些方法对他们做增强
    //这里是拦截service包下的所有类,这个粒度可以随意控制,大到所有的类,小到针对某一个方法
    @Around("execution(* com.example.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.当我们的方法被调用时,就会被切面类捕获到

@Component
public class Test {

    @Autowired
    private UserService userService;

    public void main(String[] args){

         userService.addUser("John");
         userService.deleteUser("John");
    }
}

5.然后就会输出如下信息

Adding user: John
execution(void com.example.service.UserService.addUser(String)) executed in 200ms
Deleting user: John
execution(void com.example.service.UserService.deleteUser(String)) executed in 300ms

通知类型和切入点表达式==============================

这里做个小介绍,不详细说明,因为有点复杂

通知类型(Advice Types)

在 AOP 中,通知(Advice)是指在程序执行的某个切入点(Pointcut)上执行的代码。Spring AOP 提供了多种通知类型,以便在方法执行的不同阶段进行拦截和处理。主要的通知类型包括:

  1. @Before:在目标方法执行之前执行通知。
  2. @After:在目标方法执行之后执行通知(无论目标方法是否抛出异常)。
  3. @AfterReturning:在目标方法成功返回之后执行通知。
  4. @AfterThrowing:在目标方法抛出异常之后执行通知。
  5. @Around:环绕目标方法执行通知,通知可以控制目标方法是否执行。

切入点表达式(Pointcut Expressions)

切入点表达式用于匹配连接点(Join Points),以便确定哪些方法或代码块将被通知所拦截。Spring AOP 使用 AspectJ 切入点表达式语言来定义切入点表达式。

常见的切入点表达式
  1. execution:匹配方法执行。
  2. within:匹配特定类型内的方法执行。
  3. this:匹配代理对象的类型。
  4. target:匹配目标对象的类型。
  5. args:匹配方法参数。
  6. @annotation:匹配方法上指定的注解。
  • 32
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值