AOP 典型应用场景
- 1. 日志记录(Logging)
- 代码实现
- 2. 权限校验(Authentication)
- 代码实现
- 3. 性能监控(Performance Monitoring)
- 代码实现
- 4. 缓存处理(Caching)
- 代码实现
- 5. 重试机制(Retry)
- 代码实现
- 6. 事务管理(Transaction Management)
- 代码实现
- 7. 接口限流(Rate Limiting)
- 代码实现
- 总结表格
1. 日志记录(Logging)
场景:自动记录方法的入参、返回值、执行时间和异常信息。
代码实现
1. 自定义日志注解:
// annotation/Loggable.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {String tag() default "DEFAULT";
}
2. 切面逻辑:
// aop/LoggingAspect.java
@Aspect
@Component
public class LoggingAspect {private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);@Around("@annotation(loggable)")public Object logMethod(ProceedingJoinPoint pjp, Loggable loggable) throws Throwable {String methodName = pjp.getSignature().getName();String className = pjp.getTarget().getClass().getSimpleName();String tag = loggable.tag();// 记录方法开始logger.info("[{}] {}.{}() 入参: {}", tag, className, methodName, Arrays.toString(pjp.getArgs()));long startTime = System.currentTimeMillis();try {Object result = pjp.proceed();long duration = System.currentTimeMillis() - startTime;// 记录方法结束logger.info("[{}] {}.{}() 耗时: {}ms 返回: {}", tag, className, methodName, duration, result);return result;} catch (Exception e) {// 记录异常logger.error("[{}] {}.{}() 异常: {}", tag, className, methodName, e.getMessage(), e);throw e;}}
}
3. 业务类使用:
// service/UserService.java
@Service
public class UserService {@Loggable(tag = "USER-SERVICE")public String getUserById(Long id) {return "User-" + id; // 模拟数据库查询}
}
4. 测试运行:
// MainApp.java
public class MainApp {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = context.getBean(UserService.class);userService.getUserById(123L);context.close();}
}
输出结果:
[USER-SERVICE] UserService.getUserById() 入参: [123]
[USER-SERVICE] UserService.getUserById() 耗时: 2ms 返回: User-123
2. 权限校验(Authentication)
场景:验证用户是否具有访问特定方法的权限。
代码实现
1. 自定义权限注解:
// annotation/RequireRole.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequireRole {String value() default "USER";
}
2. 切面逻辑:
// aop/SecurityAspect.java
@Aspect
@Component
public class SecurityAspect {// 模拟当前用户角色private String currentUserRole = "ADMIN";@Before("@annotation(requireRole)")public void checkPermission(JoinPoint jp, RequireRole requireRole) {String requiredRole = requireRole.value();if (!requiredRole.equals(currentUserRole)) {throw new SecurityException("权限不足! 需要角色: " + requiredRole);}}
}
3. 业务类使用:
// service/AdminService.java
@Service
public class AdminService {@RequireRole("ADMIN")public void deleteDatabase() {System.out.println("数据库已删除!"); // 危险操作}
}
4. 测试运行:
public class MainApp {public static void main(String[] args) {try {AdminService adminService = context.getBean(AdminService.class);adminService.deleteDatabase();} catch (Exception e) {System.out.println("错误: " + e.getMessage());}}
}
输出结果:
数据库已删除! // 如果currentUserRole="ADMIN"
错误: 权限不足! 需要角色: ADMIN // 如果currentUserRole="USER"
3. 性能监控(Performance Monitoring)
场景:统计方法执行耗时,用于性能分析。
代码实现
1. 切面逻辑:
// aop/PerformanceAspect.java
@Aspect
@Component
public class PerformanceAspect {@Around("execution(* com.example.service.*.*(..))")public Object monitorPerformance(ProceedingJoinPoint pjp) throws Throwable {long start = System.currentTimeMillis();Object result = pjp.proceed();long duration = System.currentTimeMillis() - start;String methodName = pjp.getSignature().getName();System.out.println("方法 " + methodName + " 执行耗时: " + duration + "ms");return result;}
}
2. 业务类:
// service/DataProcessor.java
@Service
public class DataProcessor {public void process() throws InterruptedException {Thread.sleep(500); // 模拟耗时操作}
}
3. 测试输出:
方法 process 执行耗时: 503ms
4. 缓存处理(Caching)
场景:缓存方法返回值,减少重复计算。
代码实现
1. 自定义缓存注解:
// annotation/Cacheable.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cacheable {String keyPrefix() default "";int ttl() default 300; // 缓存时间(秒)
}
2. 切面逻辑:
// aop/CacheAspect.java
@Aspect
@Component
public class CacheAspect {private Map<String, Object> cache = new ConcurrentHashMap<>();@Around("@annotation(cacheable)")public Object handleCache(ProceedingJoinPoint pjp, Cacheable cacheable) throws Throwable {String key = cacheable.keyPrefix() + Arrays.toString(pjp.getArgs());if (cache.containsKey(key)) {System.out.println("从缓存获取数据: " + key);return cache.get(key);}Object result = pjp.proceed();cache.put(key, result);System.out.println("将数据存入缓存: " + key);return result;}
}
3. 业务类使用:
// service/ProductService.java
@Service
public class ProductService {@Cacheable(keyPrefix = "product:")public String getProductInfo(String productId) {System.out.println("实际查询数据库...");return "Info-" + productId;}
}
4. 测试结果:
productService.getProductInfo("P100"); // 输出: 实际查询数据库... 将数据存入缓存: product:[P100]
productService.getProductInfo("P100"); // 输出: 从缓存获取数据: product:[P100]
5. 重试机制(Retry)
场景:在方法执行失败时自动重试。
代码实现
1. 自定义重试注解:
// annotation/Retry.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {int maxAttempts() default 3;
}
2. 切面逻辑:
// aop/RetryAspect.java
@Aspect
@Component
public class RetryAspect {@Around("@annotation(retry)")public Object retryOperation(ProceedingJoinPoint pjp, Retry retry) throws Throwable {int attempts = 0;Exception lastException;do {attempts++;try {return pjp.proceed();} catch (Exception e) {lastException = e;System.out.println("第 " + attempts + " 次尝试失败");}} while (attempts < retry.maxAttempts());throw lastException;}
}
3. 业务类使用:
// service/PaymentService.java
@Service
public class PaymentService {private int callCount = 0;@Retry(maxAttempts = 5)public void processPayment() {callCount++;if (callCount < 3) {throw new RuntimeException("支付网关超时");}System.out.println("支付成功!");}
}
4. 测试输出:
第 1 次尝试失败
第 2 次尝试失败
支付成功!
6. 事务管理(Transaction Management)
场景:自动管理数据库事务(简化版示例)。
代码实现
1. 事务管理器伪代码:
// util/TransactionManager.java
@Component
public class TransactionManager {public void begin() {System.out.println("开启事务");}public void commit() {System.out.println("提交事务");}public void rollback() {System.out.println("回滚事务");}
}
2. 切面逻辑:
// aop/TransactionAspect.java
@Aspect
@Component
public class TransactionAspect {@Autowiredprivate TransactionManager txManager;@Around("@annotation(com.example.annotation.Transactional)")public Object manageTransaction(ProceedingJoinPoint pjp) throws Throwable {txManager.begin();try {Object result = pjp.proceed();txManager.commit();return result;} catch (Exception e) {txManager.rollback();throw e;}}
}
3. 业务类使用:
// service/OrderService.java
@Service
public class OrderService {@Transactionalpublic void createOrder() {System.out.println("执行订单创建逻辑...");// 模拟数据库操作}
}
4. 测试输出:
开启事务
执行订单创建逻辑...
提交事务
7. 接口限流(Rate Limiting)
场景:限制接口的调用频率。
代码实现
1. 限流注解:
// annotation/RateLimit.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {int value() default 5; // 每秒允许的最大请求数
}
2. 切面逻辑:
// aop/RateLimitAspect.java
@Aspect
@Component
public class RateLimitAspect {private Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();@Around("@annotation(rateLimit)")public Object limit(ProceedingJoinPoint pjp, RateLimit rateLimit) throws Throwable {String methodName = pjp.getSignature().toShortString();RateLimiter limiter = limiters.computeIfAbsent(methodName, k -> RateLimiter.create(rateLimit.value()));if (limiter.tryAcquire()) {return pjp.proceed();} else {throw new RuntimeException("接口请求过于频繁");}}
}
3. 业务类使用:
// service/ApiService.java
@Service
public class ApiService {@RateLimit(2) // 每秒最多2次调用public String getData() {return "敏感数据";}
}
总结表格
应用场景 | 核心注解 | 通知类型 | 关键实现技术 |
---|---|---|---|
日志记录 | @Loggable | @Around | Slf4j + 方法元数据获取 |
权限校验 | @RequireRole | @Before | 权限上下文 + 条件判断 |
性能监控 | 无(使用execution) | @Around | 时间计算 + 方法过滤 |
缓存处理 | @Cacheable | @Around | 本地缓存(ConcurrentHashMap) |
重试机制 | @Retry | @Around | 循环控制 + 异常捕获 |
事务管理 | @Transactional | @Around | 事务管理器模拟 |
接口限流 | @RateLimit | @Around | RateLimiter + 方法标识管理 |
注意事项:
- 所有切面类必须被 Spring 扫描到(确保包路径正确)
- 同类内部方法调用不会触发 AOP(需通过代理对象调用)
- 性能敏感场景慎用 AOP(会增加方法调用栈深度)