面向切面编程(Aspect-Oriented Programming)是一种编程范式,旨在通过将横切关注点与主要业务逻辑分离,提供一种更好的代码组织和模块化的方式。
AOP的思想是将这些横切关注点从主要业务逻辑中抽离出来,形成一个独立的模块,称为切面。切面可以定义通过预定义的方式或者在运行时动态的与主业务逻辑进行织入,从而实现对横切关注点的统一处理。
AOP可以将横切关注点从主要业务逻辑中分离出来,使主要业务逻辑更加清晰明了。
AOP可以消除重复的代码。通过使用AOP注解或配置,可以将需要切入的代码逻辑集中到切面中,从而避免在每个地方重复编写相同的代码。当切面需要修改时,只需修改一处逻辑,即可实现全局的变更。
AOP可以降低代码的复杂性。通过将横切关注点与主要业务逻辑分离,使得主要业务逻辑更加专注和清晰,减少了代码的混杂程度,提高了代码的可读性和可维护性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dVNw0KX6-1692435041635)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/769234ff24bc42c6a90d4c4dfe2130a2~tplv-k3u1fbpfcp-zoom-1.image)]
下面是一个简单的例子,说明 AOP 如何解决日志记录的问题:
假设我们有一个类 UserService,其中包含了一些用户管理的方法,如 createUser()、deleteUser() 等。我们希望在每个方法执行前后记录日志。
public class UserService {
public void createUser(User user) {
Logger.log("Creating user: " + user.getName());
// 执行创建用户的逻辑
Logger.log("User created: " + user.getName());
}
public void deleteUser(String userId) {
Logger.log("Deleting user: " + userId);
// 执行删除用户的逻辑
Logger.log("User deleted: " + userId);
}
}
public aspect LoggingAspect {
before(): execution(public void UserService.*(..)) {
Logger.log("Method execution started: " + thisJoinPoint.getSignature().getName());
}
after(): execution(public void UserService.*(..)) {
Logger.log("Method execution completed: " + thisJoinPoint.getSignature().getName());
}
}
public class UserService {
public void createUser(User user) {
// 执行创建用户的逻辑
}
public void deleteUser(String userId) {
// 执行删除用户的逻辑
}
}
CGLIB(Code Generation Library)是基于字节码生成的动态代理库,它通过生成目标类的子类来实现动态代理。相对于 JDK 的动态代理,CGLIB 可以代理没有实现接口的类。
cglib动态代理流程:
图片引用自: Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现
JDK(Java Development Kit)提供了一种基于接口的动态代理机制,通过生成代理类实现对目标类的代理。JDK 动态代理只能代理实现了接口的类。