1. 深入理解AOP的核心概念
在Java企业级开发中,AOP(面向切面编程)是一种非常重要的编程范式。作为一名有着多年Spring开发经验的工程师,我经常需要向团队新人解释AOP的概念。简单来说,AOP就像是在你的业务代码中插入"钩子",让你可以在不修改原有代码的情况下,为程序添加额外的功能。
1.1 AOP的核心组件解析
让我们先来看看AOP的几个关键概念:
-
切面(Aspect):这是你要添加的横切关注点的模块化实现。比如,你可以创建一个日志切面,用来记录所有服务层方法的调用情况。
-
连接点(Joinpoint):这是程序执行过程中的特定点,比如方法调用、异常抛出等。在Spring AOP中,连接点总是代表方法的执行。
-
通知(Advice):这是在特定连接点上执行的动作。常见的有:
- @Before:方法执行前
- @After:方法执行后(无论成功或异常)
- @AfterReturning:方法成功返回后
- @AfterThrowing:方法抛出异常后
- @Around:可以完全控制方法执行过程
-
切入点(Pointcut):这是一个表达式,用来匹配哪些连接点需要被通知。比如
execution(* com.example.service.*.*(..))会匹配service包下所有类的所有方法。
1.2 AOP解决了什么问题
在实际项目中,我们经常会遇到一些横跨多个模块的功能需求,比如:
- 日志记录:需要在每个重要方法调用前后记录日志
- 事务管理:需要在业务方法执行前后管理事务
- 权限检查:需要在方法执行前验证权限
- 性能监控:需要统计方法执行时间
如果把这些逻辑都写在业务代码里,会导致代码重复、耦合度高、难以维护。AOP通过将这些横切关注点模块化,实现了:
- 代码复用:相同的功能只需编写一次
- 关注点分离:业务逻辑和横切逻辑解耦
- 可维护性:修改横切逻辑时只需修改一处
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Spring AOP的实现机制
2.1 Spring AOP的两种代理方式
Spring AOP底层使用了两种代理机制:
2.1.1 JDK动态代理
当目标对象实现了至少一个接口时,Spring默认使用JDK动态代理。这种代理方式的特点是:
- 基于接口实现
- 使用Java反射API
- 代理类会实现目标接口
- 通过InvocationHandler处理调用
java复制public class JdkProxyDemo {
public static void main(String[] args) {
UserService target = new UserServiceImpl();
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method: " + method.getName());
return result;
}
}
);
proxy.doSomething();
}
}
2.1.2 CGLIB代理
当目标对象没有实现接口时,Spring会自动切换到CGLIB代理
