Spring AOP 核心概念与实践指南
第一章:AOP 核心概念与基础应用
1.1 AOP 核心思想
- 面向切面编程:通过横向抽取机制解决代码重复问题(如日志、事务、安全等)
- 核心优势:不修改源代码增强功能,提高代码复用性和可维护性
1.2 基础环境搭建(Maven 依赖)
<dependencies>
<!-- Spring Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- AOP 支持 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
<!-- 其他必要依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
1.3 事务管理案例实践
AccountServiceImpl 核心方法
public void saveAll(Account acc1, Account acc2) {
// 原始业务逻辑
accountDao.save(acc1);
accountDao.save(acc2);
}
动态代理实现事务增强
public class JdkProxy {
public static Object getProxy(AccountService target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
try {
TxUtils.startTransaction();
Object result = method.invoke(target, args);
TxUtils.commit();
return result;
} catch (Exception e) {
TxUtils.rollback();
throw e;
} finally {
TxUtils.close();
}
});
}
}
第二章:AOP 核心术语与 XML 配置
2.1 七大核心概念
- Joinpoint(连接点):可被拦截的方法(Spring 仅支持方法级别)
- Pointcut(切入点):实际被增强的方法集合
- Advice(通知):增强逻辑的具体实现
- Target(目标对象):被代理的原始对象
- Weaving(织入):将增强应用到目标对象的过程
- Proxy(代理):增强后生成的新对象
- Aspect(切面):切入点 + 通知的组合体
2.2 XML 配置实战
Spring 配置模板
<aop:config>
<aop:aspect ref="txAspect">
<aop:before
method="beginTransaction"
pointcut="execution(* com.example.service.*.*(..))"/>
</aop:aspect>
</aop:config>
切入点表达式详解
execution([修饰符] 返回类型 包名.类名.方法名(参数))
- 常用通配符:
*
匹配任意内容..
匹配任意包路径或参数列表- 示例:
execution(* com.example..*Service.*(..))
2.3 五种通知类型
通知类型 | XML 标签 | 执行时机 |
---|---|---|
前置通知 | <aop:before> | 方法执行前 |
后置通知 | <aop:after-returning> | 方法正常返回后 |
异常通知 | <aop:after-throwing> | 方法抛出异常时 |
最终通知 | <aop:after> | 方法最终结束 |
环绕通知 | <aop:around> | 方法执行前后均可控制 |
环绕通知示例
public Object around(ProceedingJoinPoint pjp) throws Throwable {
try {
System.out.println("前置增强");
Object result = pjp.proceed();
System.out.println("后置增强");
return result;
} catch (Exception e) {
System.out.println("异常处理");
throw e;
}
}
第三章:注解驱动 AOP 开发
3.1 快速入门
切面类配置
@Aspect
@Component
public class LogAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint jp) {
System.out.println("方法执行前: " + jp.getSignature());
}
}
启用 AOP 注解支持
<!-- XML 方式 -->
<aop:aspectj-autoproxy/>
<!-- 纯注解方式 -->
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.example")
public class AppConfig {}
3.2 注解通知类型
注解 | 等效 XML | 说明 |
---|---|---|
@Before | 方法执行前 | |
@AfterReturning | 方法正常返回后 | |
@AfterThrowing | 方法抛出异常时 | |
@After | 方法最终结束 | |
@Around | 环绕通知 |
3.3 最佳实践建议
-
切面组织原则:
- 按功能模块划分切面(如日志切面、事务切面)
- 使用
@Pointcut
统一管理切入点
@Aspect public class SystemArchitecture { @Pointcut("within(com.example.web..*)") public void inWebLayer() {} }
-
性能优化技巧:
- 避免在切面中执行耗时操作
- 使用条件表达式减少不必要的增强
-
常见问题排查:
- 确保 Aspect 类被 Spring 管理(添加@Component)
- 检查切入点表达式是否匹配目标方法
- 确认是否启用自动代理(@EnableAspectJAutoProxy)
第四章:AOP 应用场景与进阶
4.1 典型应用场景
- 声明式事务管理
- 统一日志记录
- 权限控制与安全检查
- 性能监控与统计
- 异常统一处理
4.2 高级特性
组合切入点表达式
@Pointcut("execution(* com.example.dao.*.*(..))")
public void dataAccessOperation() {}
@Pointcut("execution(* com.example.service.*.*(..))")
public void businessService() {}
@Before("dataAccessOperation() || businessService()")
public void combinedPointcut() {
// 组合逻辑
}
自定义注解实现 AOP
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuditLog {}
@Aspect
@Component
public class AuditAspect {
@Around("@annotation(AuditLog)")
public Object audit(ProceedingJoinPoint pjp) throws Throwable {
// 审计逻辑实现
}
}
通过系统学习 Spring AOP 的核心概念、配置方式和实践技巧,开发者可以更高效地实现业务逻辑与非功能性需求的解耦,构建更健壮、可维护的企业级应用。