面向切面编程

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

什么是面向切面编程

面向切面编程(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 实战派》
相关推荐
meichaoWen13 分钟前
【CSS】CSS 面试知多少
前端·css
我血条子呢18 分钟前
【预览PDF】前端预览pdf
前端·pdf·状态模式
90后的晨仔33 分钟前
报错 找不到“node”的类型定义文件。 程序包含该文件是因为: 在 compilerOptions 中指定的类型库 "node" 的入口点 。
前端
90后的晨仔1 小时前
5分钟搭建你的第一个TypeScript项目
前端·typescript
zcl_19911 小时前
记一次ThreadLocal导致的生产事故
java
专注前端30年1 小时前
Vue2 中 v-if 与 v-show 深度对比及实战指南
开发语言·前端·vue
RoboWizard1 小时前
怎么判断我的电脑是否支持PCIe 5.0 SSD?Kingston FURY Renegade G5
java·spring·智能手机·电脑·金士顿
90后的晨仔1 小时前
TypeScript是什么?为什么前端必须学它?
前端
武子康1 小时前
大数据-139 ClickHouse MergeTree 最佳实践:Replacing 去重、Summing 求和、分区设计与物化视图替代方案
大数据·后端·nosql
用户47949283569152 小时前
从 58MB 到 2.6MB:我是如何将 React 官网性能提升 95% 的
前端·javascript