面向切面编程

本文,我们来谈谈面向切面编程。

什么是面向切面编程

面向切面编程(Aspect Oriented Program, 简称 AOP)是一种编程范式,用于解藕系统中的横切关注点。

这很抽象。

我们换种理解~

面向切面编程把业务功能分为核心、非核心两部分。比如:

  • 核心业务功能:用户登陆、增加数据、删除数据
  • 非核心业务功能:性能统计、日志、事务管理

Spring 的面向编程思想中,非核心业务功能被定义为切面 。核心业务功能和切面功能(非核心功能)被分别进行独立开发,然后把切面功能和核心业务功能编织 在一起,这就是 AOP

AOP 中的概念

术语 解析
切入点 pointcut 在哪些类、哪些方法上切入
通知 advice 在方法前、方法后、方法前后做了什么
切面 aspect 切面 = 切入点 + 通知
织入 weaving 把切面加入对象,并创建出代理对象的过程
环绕通知 AOP 中最强大、灵活的通知,它集成了前置和后置通知,保留了连接点原有的方法

案例图解

未使用 AOP

使用 AOP

简单案例

假设我们开发一个简单用户管理系统。

添加 aspect 依赖:

xml 复制代码
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.19</version>
</dependency>

我们创建一个切面类,定义了我们要应用的横切关注点

java 复制代码
package com.launch;

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

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.launch.UserService.addUser(..))")
    public void logBeforeAddUser() {
        System.out.println("Before adding a user...");
    }

    @Before("execution(* com.launch.UserService.deleteUser(..))")
    public void logBeforeDeleteUser() {
        System.out.println("Before deleting a user...");
    }
}

我们创建了名为 LoggingAspect 的切面类,并使用 @Before 注释定义了两个通知方法。这两个通知分别在执行 com.example.UserService.addUser()com.example.UserService.deleteUser() 方法之前打印日志。

接下来,我们创建名为 UserService 类,并添加 @Service 注解:

java 复制代码
package com.launch;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void addUser(String username) {
        // add logic
        System.out.println("add logic " + username);
    }
    public void deleteUser(String username) {
        // remove logic
        System.out.println("delete logic " + username);
    }
}

然后我们在程序入口文件中添加 @EnableAspectJAutoProxy 注解,以启用 AOP

java 复制代码
package com.launch;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy
public class LaunchApplication {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(LaunchApplication.class);
        app.run(args);
    }

}

然后我们创建名为 JimmyController 的类进行测试:

java 复制代码
package com.launch;

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

@Controller
public class JimmyController {
    @Autowired
    private UserService userService;

    @RequestMapping("/add_and_delete")
    public String addUser() {
        userService.addUser("Jimmy");
        userService.deleteUser("Jimmy");
        return "Add Jimmy.";
    }
}

这里我们触发 Get 请求 http://localhost:8080/add_and_delete 接口就可以看到下面的结果:

参考

  • 《Spring Boot 实战派》
相关推荐
涡能增压发动积7 小时前
同样的代码循环 10次正常 循环 100次就抛异常?自定义 Comparator 的 bug 让我丢尽颜面
后端
云烟成雨TD7 小时前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
Wenweno0o7 小时前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
于慨7 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz7 小时前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
swg3213217 小时前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
从前慢丶7 小时前
前端交互规范(Web 端)
前端
tyung7 小时前
一个 main.go 搞定协作白板:你画一笔,全世界都看见
后端·go
gelald7 小时前
SpringBoot - 自动配置原理
java·spring boot·后端
殷紫川7 小时前
深入理解 AQS:从架构到实现,解锁 Java 并发编程的核心密钥
java