AOP应用场景
AOP将横切关注点从业务逻辑中分离,以下是最典型的应用场景。
日志记录
统一记录方法调用日志,无需在业务代码中手动添加。
Java
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable {
String method = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
log.info("调用方法: {}, 参数: {}", method, Arrays.toString(args));
Object result = joinPoint.proceed();
log.info("方法返回: {}, 结果: {}", method, result);
return result;
}
}
事务管理
Spring声明式事务基于AOP实现,无需手动管理事务。
Java
@Service
public class OrderService {
@Transactional
public void createOrder(Order order) {
// 方法执行前自动开启事务
orderDao.insert(order);
inventoryDao.reduce(order.getProductId(), order.getQuantity());
// 方法正常返回自动提交,异常自动回滚
}
}
权限控制
统一进行权限校验,避免权限代码散落各处。
Java
@Aspect
@Component
public class PermissionAspect {
@Before("@annotation(requireRole)")
public void checkPermission(JoinPoint joinPoint, RequireRole requireRole) {
String role = requireRole.value();
String currentRole = SecurityContext.getCurrentUserRole();
if (!role.equals(currentRole)) {
throw new AccessDeniedException("权限不足");
}
}
}
// 使用注解标记需要权限的方法
@RequireRole("ADMIN")
public void deleteUser(Long id) {
userDao.delete(id);
}
性能监控
统计方法执行时间,定位性能瓶颈。
Java
@Aspect
@Component
public class PerformanceAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object monitorPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long elapsed = System.currentTimeMillis() - start;
String method = joinPoint.getSignature().getName();
if (elapsed > 1000) {
log.warn("方法 {} 执行耗时: {}ms", method, elapsed);
}
return result;
}
}
缓存
方法返回值缓存,减少重复计算或数据库访问。
Java
@Aspect
@Component
public class CacheAspect {
private Map<String, Object> cache = new ConcurrentHashMap<>();
@Around("@annotation(cacheable)")
public Object cacheResult(ProceedingJoinPoint joinPoint, Cacheable cacheable) throws Throwable {
String key = generateKey(joinPoint);
if (cache.containsKey(key)) {
return cache.get(key);
}
Object result = joinPoint.proceed();
cache.put(key, result);
return result;
}
}
异常处理
统一捕获和处理异常,避免try-catch代码污染业务逻辑。
Java
@Aspect
@Component
public class ExceptionAspect {
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))",
throwing = "ex")
public void handleException(JoinPoint joinPoint, Exception ex) {
String method = joinPoint.getSignature().getName();
log.error("方法 {} 执行异常: {}", method, ex.getMessage());
// 统一异常处理,如发送告警、记录日志
alertService.sendAlert(ex);
}
}
应用场景汇总
| 场景 | 通知类型 | 典型应用 |
|---|---|---|
| 日志记录 | @Around | 方法调用日志 |
| 事务管理 | @Around | @Transactional底层实现 |
| 权限控制 | @Before | 接口权限校验 |
| 性能监控 | @Around | 方法耗时统计 |
| 缓存 | @Around | 返回值缓存 |
| 异常处理 | @AfterThrowing | 统一异常处理 |
要点总结
- 日志记录:统一记录方法调用日志
- 事务管理:Spring声明式事务的核心实现
- 权限控制:结合注解实现接口权限校验
- 性能监控:统计方法执行时间
- 缓存:缓存方法返回值,减少重复计算
- 异常处理:统一捕获处理异常
📝 发现内容有误?点击此处直接编辑