面向切面编程

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

什么是面向切面编程

面向切面编程(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 实战派》
相关推荐
用户新30 分钟前
V8引擎 精品漫游指南--Ignition篇(下 一) 动态执行前的事情
前端·javascript
abcnull2 小时前
用javaparser做精准测试
java·ast·静态代码分析·精准测试·javaparser
叶小鸡2 小时前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
@PHARAOH2 小时前
WHAT - GitLens vs Fork
前端
yqcoder2 小时前
前端性能优化:如何减少重绘与重排?
前端·性能优化
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
juniperhan2 小时前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_180079054733 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
c++之路3 小时前
C++23概述
java·c++·c++23
洋子3 小时前
Yank Note 系列 13 - 让 AI Agent 进入笔记工作流
前端·人工智能