📅  最后修改于: 2023-12-03 15:05:15.767000             🧑  作者: Mango
在面向对象编程(OOP)中,我们主要关注对象的行为和特性,采用一种基于类的封装方式来组织代码,每个类都包含了一组属性和方法,方法是类的行为,属性是类的数据。
而在面向切面编程(AOP)中,我们主要关注横切关注点(cross-cutting concerns),如日志、事务管理、安全等,这些关注点可能分布在多个类或对象中,通过切面的概念来对其进行统一管理,切面可以看作是对类或对象的某些方法进行增强,而不是修改它们的代码。这样可以让我们更加专注于核心业务逻辑,而不用担心这些横切关注点会给我们的代码带来复杂度和重复性的问题。
本篇文章将重点介绍 Spring Boot 中 AOP 和 OOP 之间的区别,以及如何使用 Spring Boot AOP 来实现切面编程。
Spring Boot 提供了 AOP 的支持,通过使用 Spring AOP 模块和 AspectJ 工具,可以方便地实现对 Java 方法的切面编程。下面我们来看一下 Spring Boot AOP 的基本概念和使用方式。
Join Point 是指程序执行过程中的一个步骤,比如方法调用、异常抛出等等,这些步骤都可以被切面拦截并进行增强。Spring Boot AOP 支持以下五种 Join Point:
Pointcut 是一个表达式,用于指定切面的 Join Point,只有匹配到 Pointcut 的 Join Point 才会被切面拦截并进行增强。
Pointcut 表达式的语法比较复杂,主要包括以下几种类型:
execution(* com.example.service.*.*(..))
表示匹配 com.example.service 包中所有类的所有方法。within(com.example.service.*)
表示匹配 com.example.service 包中所有类。this(com.example.service.FooService)
表示匹配当前对象为 FooService 类型的执行方法。target(com.example.service.FooService)
表示匹配目标对象为 FooService 类型的执行方法。args(String, ..)
表示匹配第一个参数为 String 类型的执行方法。@annotation(org.springframework.transaction.annotation.Transactional)
表示匹配所有使用 @Transactional 注解的方法。Advice 是切面在 Join Point 上执行的动作,包括 Before、After、Around、AfterReturning、AfterThrowing 等几种类型。
Aspect 是一个类,包含了一组 Pointcut 和 Advice,用于增强特定的 Join Point,比如打印日志、参数验证等。
下面通过一个简单的例子来说明如何在 Spring Boot 中使用 AOP:
定义一个切面类,实现了 Before 和 AfterReturning 两种 Advice:
@Aspect
@Component
public class UserServiceAspect {
@Before("execution(* com.example.service.UserService.addUser(..))")
public void beforeAdvice(JoinPoint joinPoint) {
System.out.println("Before addUser method...");
}
@AfterReturning("execution(* com.example.service.UserService.addUser(..))")
public void afterReturningAdvice(JoinPoint joinPoint) {
System.out.println("After addUser method...");
}
}
定义一个 UserService 接口和实现类:
public interface UserService {
void addUser(String username, String password);
}
@Service
public class UserServiceImpl implements UserService {
@Override
public void addUser(String username, String password) {
System.out.println("Adding user: " + username);
}
}
在启动类中添加 @EnableAspectJAutoProxy 注解,并手动注册切面类:
@SpringBootApplication
@EnableAspectJAutoProxy
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public UserServiceAspect userServiceAspect() {
return new UserServiceAspect();
}
}
执行 addUser 方法:
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/addUser")
public void addUser() {
userService.addUser("admin", "123456");
}
}
访问 http://localhost:8080/addUser,控制台输出:
Before addUser method...
Adding user: admin
After addUser method...
可以看到 Before 和 AfterReturning 两种 Advice 成功地对 addUser 方法进行了增强。
本篇文章介绍了 Spring Boot 中 AOP 和 OOP 之间的区别,以及如何在 Spring Boot 中使用 AOP 实现切面编程。通过 AOP,我们可以方便地对代码中的横切关注点进行统一管理,提高代码的可重用性和可维护性。