

在现代Java企业级开发中,面向切面编程(AOP)已经成为不可或缺的编程范式。SpringBoot作为Spring生态系统的集大成者,为AOP提供了强大而优雅的支持,让开发者能够以声明式的方式处理横切关注点,如日志记录、性能监控、安全控制等。
本文将深入探讨SpringBoot AOP的核心概念、实现机制和实战应用,通过丰富的代码示例和实际场景,帮助读者全面掌握AOP编程技术。文章采用"总分总"的结构,从基础概念到高级特性,再到企业级最佳实践,为中高级Java开发者提供系统性的学习指南。
面向切面编程(Aspect-Oriented Programming)是一种编程范式,它通过预编译方式和运行期动态代理实现程序功能的统一维护。AOP是对面向对象编程(OOP)的有力补充,主要用于处理系统中分布于各个模块的横切关注点。
/**
* AOP核心概念示例
* 以用户服务为例说明各个概念
*/
@Service
public class UserService {
// 连接点(Join Point) - 程序执行过程中的特定点
public User getUserById(Long id) {
// 业务逻辑
return userRepository.findById(id);
}
// 连接点 - 另一个可以被拦截的方法
public void updateUser(User user) {
// 业务逻辑
userRepository.save(user);
}
}/**
* 切面定义示例
* 展示不同类型的通知
*/
@Aspect
@Component
public class LoggingAspect {
private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
// 切点定义 - 定义在哪些连接点上应用通知
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}
// 前置通知 - 在目标方法执行前执行
@Before("serviceLayer()")
public void logBefore(JoinPoint joinPoint) {
logger.info("执行方法: {}", joinPoint.getSignature().getName());
}
// 后置通知 - 在目标方法执行后执行(无论是否抛出异常)
@After("serviceLayer()")
public void logAfter(JoinPoint joinPoint) {
logger.info("方法执行完成: {}", joinPoint.getSignature().getName());
}
// 返回通知 - 在目标方法正常返回后执行
@AfterReturning(pointcut = "serviceLayer()", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
logger.info("方法 {} 返回值: {}", joinPoint.getSignature().getName(), result);
}
// 异常通知 - 在目标方法抛出异常后执行
@AfterThrowing(pointcut = "serviceLayer()", throwing = "exception")
public void logAfterThrowing(JoinPoint joinPoint, Exception exception) {
logger.error("方法 {} 抛出异常: {}", joinPoint.getSignature().getName(), exception.getMessage());
}
// 环绕通知 - 围绕目标方法执行
@Around("serviceLayer()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
logger.info("方法 {} 执行时间: {}ms", joinPoint.getSignature().getName(), endTime - startTime);
return result;
} catch (Exception e) {
logger.error("方法执行异常", e);
throw e;
}
}
}
SpringBoot为AOP提供了开箱即用的自动配置,只需添加相应依赖即可启用AOP功能:
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>/**
* AOP配置类
* SpringBoot自动配置AOP,也可以手动配置
*/
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
/**
* 自定义切面Bean
*/
@Bean
public LoggingAspect loggingAspect() {
return new LoggingAspect();
}
}/**
* 代理机制演示
* SpringBoot AOP支持JDK动态代理和CGLIB代理
*/
@Component
public class ProxyDemoService {
@Value("${spring.aop.proxy-target-class:true}")
private boolean proxyTargetClass;
/**
* 接口方法 - 可以使用JDK动态代理
*/
public void interfaceMethod() {
System.out.println("接口方法执行");
}
/**
* 类方法 - 需要使用CGLIB代理
*/
public final void finalMethod() {
System.out.println("final方法不能被代理");
}
/**
* 私有方法 - 不能被代理
*/
private void privateMethod() {
System.out.println("私有方法不能被代理");
}
}/**
* 传统编程方式 - 横切关注点与业务逻辑混合
*/
@Service
public class TraditionalUserService {
private static final Logger logger = LoggerFactory.getLogger(TraditionalUserService.class);
public User getUserById(Long id) {
// 日志记录
logger.info("开始获取用户信息,ID: {}", id);
long startTime = System.currentTimeMillis();
try {
// 参数校验
if (id == null || id <= 0) {
throw new IllegalArgumentException("用户ID不能为空或小于等于0");
}
// 权限检查
if (!hasPermission("USER_READ")) {
throw new SecurityException("没有读取用户信息的权限");
}
// 核心业务逻辑
User user = userRepository.findById(id);
// 性能监控
long endTime = System.currentTimeMillis();
logger.info("获取用户信息完成,耗时: {}ms", endTime - startTime);
return user;
} catch (Exception e) {
logger.error("获取用户信息失败", e);
throw e;
}
}
private boolean hasPermission(String permission) {
// 权限检查逻辑
return true;
}
}/**
* AOP编程方式 - 关注点分离
*/
@Service
public class AopUserService {
@Autowired
private UserRepository userRepository;
/**
* 纯净的业务逻辑
* 横切关注点通过AOP处理
*/
@LogExecutionTime
@ValidateParams
@RequirePermission("USER_READ")
public User getUserById(Long id) {
return userRepository.findById(id);
}
}
/**
* 性能监控切面
*/
@Aspect
@Component
public class PerformanceMonitorAspect {
private static final Logger logger = LoggerFactory.getLogger(PerformanceMonitorAspect.class);
@Around("@annotation(LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
logger.info("方法 {} 执行时间: {}ms",
joinPoint.getSignature().getName(), endTime - startTime);
return result;
} catch (Exception e) {
logger.error("方法执行异常", e);
throw e;
}
}
}
/**
* 自定义注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidateParams {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequirePermission {
String value();
}
/**
* 标准切面类定义
* 展示切面类的基本结构和最佳实践
*/
@Aspect
@Component
@Slf4j
public class StandardAspect {
/**
* 切面优先级
* 数值越小优先级越高
*/
@Order(1)
/**
* 切点定义 - 可重用的切点表达式
*/
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}
@Pointcut("@annotation(com.example.annotation.Cacheable)")
public void cacheableMethod() {}
/**
* 组合切点 - 使用逻辑运算符组合多个切点
*/
@Pointcut("serviceLayer() && cacheableMethod()")
public void cacheableServiceMethod() {}
}/**
* 切面实例化模式
* 演示不同的切面实例化策略
*/
@Aspect("perthis(serviceLayer())")
@Component
public class PerInstanceAspect {
private int invocationCount = 0;
@Before("serviceLayer()")
public void beforeAdvice() {
invocationCount++;
log.info("当前实例调用次数: {}", invocationCount);
}
}
/**
* 单例切面(默认模式)
*/
@Aspect
@Component
public class SingletonAspect {
private final AtomicInteger globalCount = new AtomicInteger(0);
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice() {
int count = globalCount.incrementAndGet();
log.info("全局调用次数: {}", count);
}
}/**
* 前置通知详细应用
*/
@Aspect
@Component
public class BeforeAdviceAspect {
/**
* 基本前置通知
*/
@Before("execution(* com.example.service.UserService.save*(..))")
public void beforeSave(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
log.info("准备保存数据: {}", Arrays.toString(args));
}
/**
* 带参数绑定的前置通知
*/
@Before("execution(* com.example.service.UserService.updateUser(..)) && args(user)")
public void beforeUpdate(User user) {
log.info("准备更新用户: {}", user.getName());
// 可以修改参数对象的属性
user.setUpdateTime(LocalDateTime.now());
}
/**
* 条件化前置通知
*/
@Before("@annotation(auditLog)")
public void beforeAuditLog(JoinPoint joinPoint, AuditLog auditLog) {
if (auditLog.level() == AuditLevel.HIGH) {
log.warn("高级别审计操作: {}", joinPoint.getSignature().getName());
}
}
}/**
* 环绕通知高级应用
* 展示环绕通知的强大功能
*/
@Aspect
@Component
public class AroundAdviceAspect {
/**
* 性能监控环绕通知
*/
@Around("@annotation(performanceMonitor)")
public Object monitorPerformance(ProceedingJoinPoint joinPoint,
PerformanceMonitor performanceMonitor) throws Throwable {
String methodName = joinPoint.getSignature().getName();
long threshold = performanceMonitor.threshold();
StopWatch stopWatch = new StopWatch();
stopWatch.start();
try {
Object result = joinPoint.proceed();
stopWatch.stop();
long executionTime = stopWatch.getTotalTimeMillis();
if (executionTime > threshold) {
log.warn("方法 {} 执行时间 {}ms 超过阈值 {}ms",
methodName, executionTime, threshold);
} else {
log.info("方法 {} 执行时间: {}ms", methodName, executionTime);
}
return result;
} catch (Exception e) {
stopWatch.stop();
log.error("方法 {} 执行异常,耗时: {}ms",
methodName, stopWatch.getTotalTimeMillis(), e);
throw e;
}
}
/**
* 重试机制环绕通知
*/
@Around("@annotation(retryable)")
public Object retry(ProceedingJoinPoint joinPoint, Retryable retryable) throws Throwable {
int maxAttempts = retryable.maxAttempts();
long delay = retryable.delay();
Class<? extends Exception>[] retryFor = retryable.retryFor();
Exception lastException = null;
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return joinPoint.proceed();
} catch (Exception e) {
lastException = e;
// 检查是否为可重试异常
boolean shouldRetry = Arrays.stream(retryFor)
.anyMatch(exceptionClass -> exceptionClass.isInstance(e));
if (!shouldRetry || attempt == maxAttempts) {
throw e;
}
log.warn("方法 {} 第 {} 次执行失败,{}ms后重试",
joinPoint.getSignature().getName(), attempt, delay);
Thread.sleep(delay);
}
}
throw lastException;
}
}
/**
* 自定义注解定义
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PerformanceMonitor {
long threshold() default 1000; // 默认阈值1秒
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retryable {
int maxAttempts() default 3;
long delay() default 1000;
Class<? extends Exception>[] retryFor() default {Exception.class};
}/**
* execution表达式全面示例
*/
@Aspect
@Component
public class ExecutionPointcutAspect {
/**
* 基本语法:execution(修饰符 返回类型 包名.类名.方法名(参数类型))
*/
// 匹配所有public方法
@Pointcut("execution(public * *(..))")
public void publicMethods() {}
// 匹配特定包下的所有方法
@Pointcut("execution(* com.example.service.*.*(..))")
public void servicePackage() {}
// 匹配特定包及其子包下的所有方法
@Pointcut("execution(* com.example.service..*.*(..))")
public void servicePackageAndSubpackages() {}
// 匹配特定返回类型的方法
@Pointcut("execution(com.example.dto.UserDTO com.example.service.*.*(..))")
public void userDTOReturnType() {}
// 匹配特定参数类型的方法
@Pointcut("execution(* com.example.service.*.*(java.lang.Long))")
public void longParameterMethods() {}
// 匹配多个参数的方法
@Pointcut("execution(* com.example.service.*.*(java.lang.Long, java.lang.String))")
public void twoParameterMethods() {}
// 匹配任意参数的方法
@Pointcut("execution(* com.example.service.*.*(..))")
public void anyParameterMethods() {}
/**
* 复杂表达式组合
*/
@Before("publicMethods() && servicePackage() && args(id)")
public void beforePublicServiceMethod(Long id) {
log.info("执行公共服务方法,参数ID: {}", id);
}
}/**
* 多种切点表达式类型演示
*/
@Aspect
@Component
public class VariousPointcutAspect {
/**
* @annotation - 匹配带有特定注解的方法
*/
@Before("@annotation(org.springframework.transaction.annotation.Transactional)")
public void beforeTransactionalMethod() {
log.info("执行事务方法");
}
/**
* @within - 匹配带有特定注解的类中的所有方法
*/
@Before("@within(org.springframework.stereotype.Service)")
public void beforeServiceClassMethod() {
log.info("执行Service类中的方法");
}
/**
* @target - 匹配目标对象带有特定注解的方法
*/
@Before("@target(org.springframework.stereotype.Repository)")
public void beforeRepositoryMethod() {
log.info("执行Repository对象的方法");
}
/**
* @args - 匹配参数带有特定注解的方法
*/
@Before("@args(javax.validation.Valid)")
public void beforeValidatedParameterMethod() {
log.info("执行带有@Valid参数的方法");
}
/**
* within - 匹配特定类型内的方法
*/
@Before("within(com.example.service.UserService)")
public void beforeUserServiceMethod() {
log.info("执行UserService中的方法");
}
/**
* this - 匹配代理对象是特定类型的方法
*/
@Before("this(com.example.service.BaseService)")
public void beforeBaseServiceProxyMethod() {
log.info("执行BaseService代理对象的方法");
}
/**
* target - 匹配目标对象是特定类型的方法
*/
@Before("target(com.example.service.UserService)")
public void beforeUserServiceTargetMethod() {
log.info("执行UserService目标对象的方法");
}
/**
* bean - 匹配特定名称的Spring Bean
*/
@Before("bean(userService)")
public void beforeUserServiceBean() {
log.info("执行名为userService的Bean方法");
}
/**
* bean表达式支持通配符
*/
@Before("bean(*Service)")
public void beforeAnyServiceBean() {
log.info("执行任何以Service结尾的Bean方法");
}
}/**
* 参数绑定详细示例
*/
@Aspect
@Component
public class ParameterBindingAspect {
/**
* 绑定方法参数
*/
@Before("execution(* com.example.service.UserService.updateUser(..)) && args(user)")
public void beforeUpdateUser(User user) {
log.info("准备更新用户: {}", user.getName());
// 可以在这里修改参数
if (user.getUpdateTime() == null) {
user.setUpdateTime(LocalDateTime.now());
}
}
/**
* 绑定多个参数
*/
@Before("execution(* com.example.service.OrderService.createOrder(..)) && args(userId, orderItems)")
public void beforeCreateOrder(Long userId, List<OrderItem> orderItems) {
log.info("用户 {} 创建订单,商品数量: {}", userId, orderItems.size());
}
/**
* 绑定注解参数
*/
@Around("@annotation(cacheable)")
public Object handleCacheable(ProceedingJoinPoint joinPoint, Cacheable cacheable) throws Throwable {
String cacheKey = generateCacheKey(joinPoint, cacheable.key());
// 尝试从缓存获取
Object cachedResult = cacheManager.get(cacheKey);
if (cachedResult != null) {
log.info("缓存命中: {}", cacheKey);
return cachedResult;
}
// 执行方法并缓存结果
Object result = joinPoint.proceed();
cacheManager.put(cacheKey, result, cacheable.expireTime());
log.info("缓存存储: {}", cacheKey);
return result;
}
/**
* 绑定目标对象
*/
@Before("execution(* com.example.service.*.*(..)) && target(service)")
public void beforeServiceMethod(Object service) {
log.info("执行服务对象方法: {}", service.getClass().getSimpleName());
}
/**
* 绑定JoinPoint信息
*/
@Before("execution(* com.example.controller.*.*(..))")
public void beforeControllerMethod(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Object[] args = joinPoint.getArgs();
log.info("控制器方法: {}.{}",
signature.getDeclaringTypeName(),
signature.getName());
log.info("方法参数: {}", Arrays.toString(args));
log.info("参数类型: {}", Arrays.toString(method.getParameterTypes()));
}
private String generateCacheKey(ProceedingJoinPoint joinPoint, String keyExpression) {
// 缓存键生成逻辑
return joinPoint.getSignature().getName() + ":" + keyExpression;
}
}/**
* 返回值处理示例
*/
@Aspect
@Component
public class ReturnValueAspect {
/**
* 处理正常返回值
*/
@AfterReturning(pointcut = "execution(* com.example.service.UserService.getUser*(..))",
returning = "user")
public void afterReturningUser(JoinPoint joinPoint, User user) {
if (user != null) {
log.info("获取到用户: {}", user.getName());
// 可以对返回值进行后处理,但不能修改引用
user.setLastAccessTime(LocalDateTime.now());
}
}
/**
* 使用环绕通知修改返回值
*/
@Around("@annotation(responseWrapper)")
public Object wrapResponse(ProceedingJoinPoint joinPoint, ResponseWrapper responseWrapper) throws Throwable {
Object result = joinPoint.proceed();
// 包装返回值
if (responseWrapper.wrapWithApiResponse()) {
return ApiResponse.success(result);
}
return result;
}
/**
* 处理集合类型返回值
*/
@AfterReturning(pointcut = "execution(java.util.List com.example.service.*.findAll*(..))",
returning = "list")
public void afterReturningList(List<?> list) {
log.info("查询返回 {} 条记录", list != null ? list.size() : 0);
}
/**
* 处理分页返回值
*/
@AfterReturning(pointcut = "execution(org.springframework.data.domain.Page com.example.service.*.findPage*(..))",
returning = "page")
public void afterReturningPage(Page<?> page) {
log.info("分页查询: 第{}页,共{}页,总计{}条记录",
page.getNumber() + 1,
page.getTotalPages(),
page.getTotalElements());
}
/**
* 条件化返回值处理
*/
@Around("execution(* com.example.service.*.*(..))")
public Object conditionalReturnValueProcessing(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
// 根据返回值类型进行不同处理
if (result instanceof String) {
String stringResult = (String) result;
if (stringResult.length() > 100) {
log.warn("返回字符串过长: {} 字符", stringResult.length());
}
} else if (result instanceof Collection) {
Collection<?> collection = (Collection<?>) result;
if (collection.size() > 1000) {
log.warn("返回集合过大: {} 个元素", collection.size());
}
}
return result;
}
}
/**
* 自定义注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseWrapper {
boolean wrapWithApiResponse() default true;
}
/**
* API响应包装类
*/
public class ApiResponse<T> {
private int code;
private String message;
private T data;
private LocalDateTime timestamp;
public static <T> ApiResponse<T> success(T data) {
ApiResponse<T> response = new ApiResponse<>();
response.code = 200;
response.message = "success";
response.data = data;
response.timestamp = LocalDateTime.now();
return response;
}
// getter和setter方法省略
}/**
* 统一日志记录切面
* 提供方法执行日志、参数日志、异常日志等功能
*/
@Aspect
@Component
@Slf4j
public class LoggingAspect {
private final ObjectMapper objectMapper;
public LoggingAspect(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
/**
* 方法执行日志
*/
@Around("@annotation(methodLog)")
public Object logMethodExecution(ProceedingJoinPoint joinPoint, MethodLog methodLog) throws Throwable {
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
// 记录方法开始执行
if (methodLog.logArgs()) {
log.info("[{}] 开始执行方法: {}.{}, 参数: {}",
methodLog.module(), className, methodName, formatArgs(args));
} else {
log.info("[{}] 开始执行方法: {}.{}",
methodLog.module(), className, methodName);
}
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - startTime;
// 记录方法执行成功
if (methodLog.logResult() && result != null) {
log.info("[{}] 方法执行成功: {}.{}, 耗时: {}ms, 返回值: {}",
methodLog.module(), className, methodName, executionTime, formatResult(result));
} else {
log.info("[{}] 方法执行成功: {}.{}, 耗时: {}ms",
methodLog.module(), className, methodName, executionTime);
}
return result;
} catch (Exception e) {
long executionTime = System.currentTimeMillis() - startTime;
log.error("[{}] 方法执行异常: {}.{}, 耗时: {}ms, 异常信息: {}",
methodLog.module(), className, methodName, executionTime, e.getMessage(), e);
throw e;
}
}
/**
* 控制器层统一日志
*/
@Around("execution(* com.example.controller.*.*(..))")
public Object logControllerMethod(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = getCurrentRequest();
String requestId = generateRequestId();
// 设置请求ID到MDC
MDC.put("requestId", requestId);
try {
log.info("HTTP请求开始 - {} {}, 请求ID: {}",
request.getMethod(), request.getRequestURI(), requestId);
Object result = joinPoint.proceed();
log.info("HTTP请求完成 - 请求ID: {}", requestId);
return result;
} catch (Exception e) {
log.error("HTTP请求异常 - 请求ID: {}, 异常: {}", requestId, e.getMessage(), e);
throw e;
} finally {
MDC.clear();
}
}
private String formatArgs(Object[] args) {
if (args == null || args.length == 0) {
return "[]";
}
try {
return objectMapper.writeValueAsString(args);
} catch (Exception e) {
return Arrays.toString(args);
}
}
private String formatResult(Object result) {
try {
String json = objectMapper.writeValueAsString(result);
return json.length() > 500 ? json.substring(0, 500) + "..." : json;
} catch (Exception e) {
return result.toString();
}
}
private HttpServletRequest getCurrentRequest() {
return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
}
private String generateRequestId() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 8);
}
}
/**
* 方法日志注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodLog {
String module() default "DEFAULT";
boolean logArgs() default true;
boolean logResult() default true;
}/**
* 性能监控切面
* 提供方法执行时间监控、慢查询检测等功能
*/
@Aspect
@Component
@Slf4j
public class PerformanceMonitoringAspect {
private final MeterRegistry meterRegistry;
private final PerformanceProperties performanceProperties;
public PerformanceMonitoringAspect(MeterRegistry meterRegistry,
PerformanceProperties performanceProperties) {
this.meterRegistry = meterRegistry;
this.performanceProperties = performanceProperties;
}
/**
* 方法执行时间监控
*/
@Around("@annotation(timed)")
public Object monitorExecutionTime(ProceedingJoinPoint joinPoint, Timed timed) throws Throwable {
Timer.Sample sample = Timer.start(meterRegistry);
String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getTarget().getClass().getSimpleName();
try {
Object result = joinPoint.proceed();
// 记录成功执行时间
sample.stop(Timer.builder("method.execution.time")
.tag("class", className)
.tag("method", methodName)
.tag("status", "success")
.register(meterRegistry));
return result;
} catch (Exception e) {
// 记录异常执行时间
sample.stop(Timer.builder("method.execution.time")
.tag("class", className)
.tag("method", methodName)
.tag("status", "error")
.register(meterRegistry));
throw e;
}
}
/**
* 慢查询检测
*/
@Around("execution(* com.example.repository.*.*(..))")
public Object detectSlowQuery(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
String methodName = joinPoint.getSignature().getName();
try {
Object result = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - startTime;
// 检测慢查询
if (executionTime > performanceProperties.getSlowQueryThreshold()) {
log.warn("慢查询检测: 方法 {} 执行时间 {}ms 超过阈值 {}ms",
methodName, executionTime, performanceProperties.getSlowQueryThreshold());
// 发送慢查询告警
sendSlowQueryAlert(methodName, executionTime, joinPoint.getArgs());
}
return result;
} catch (Exception e) {
long executionTime = System.currentTimeMillis() - startTime;
log.error("查询异常: 方法 {} 执行时间 {}ms", methodName, executionTime, e);
throw e;
}
}
/**
* 系统资源监控
*/
@Around("execution(* com.example.service.*.*(..))")
public Object monitorSystemResources(ProceedingJoinPoint joinPoint) throws Throwable {
// 记录方法执行前的系统状态
long beforeMemory = getUsedMemory();
long beforeTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
// 记录方法执行后的系统状态
long afterMemory = getUsedMemory();
long afterTime = System.currentTimeMillis();
long memoryUsed = afterMemory - beforeMemory;
long timeUsed = afterTime - beforeTime;
// 记录资源使用情况
if (memoryUsed > performanceProperties.getMemoryThreshold() ||
timeUsed > performanceProperties.getTimeThreshold()) {
log.warn("资源使用告警: 方法 {} 内存使用 {}MB, 执行时间 {}ms",
joinPoint.getSignature().getName(),
memoryUsed / 1024 / 1024,
timeUsed);
}
return result;
} catch (Exception e) {
throw e;
}
}
private long getUsedMemory() {
Runtime runtime = Runtime.getRuntime();
return runtime.totalMemory() - runtime.freeMemory();
}
private void sendSlowQueryAlert(String methodName, long executionTime, Object[] args) {
// 发送告警逻辑(邮件、短信、钉钉等)
log.info("发送慢查询告警: 方法={}, 执行时间={}ms", methodName, executionTime);
}
}
/**
* 性能监控配置
*/
@ConfigurationProperties(prefix = "performance.monitoring")
@Data
public class PerformanceProperties {
private long slowQueryThreshold = 1000; // 慢查询阈值(毫秒)
private long memoryThreshold = 100 * 1024 * 1024; // 内存使用阈值(字节)
private long timeThreshold = 5000; // 时间阈值(毫秒)
}/**
* 权限验证切面
* 提供方法级别的权限控制
*/
@Aspect
@Component
@Slf4j
public class SecurityAspect {
private final AuthenticationService authenticationService;
private final AuthorizationService authorizationService;
public SecurityAspect(AuthenticationService authenticationService,
AuthorizationService authorizationService) {
this.authenticationService = authenticationService;
this.authorizationService = authorizationService;
}
/**
* 权限检查
*/
@Before("@annotation(requiresPermission)")
public void checkPermission(JoinPoint joinPoint, RequiresPermission requiresPermission) {
// 获取当前用户
UserContext currentUser = authenticationService.getCurrentUser();
if (currentUser == null) {
throw new UnauthorizedException("用户未登录");
}
String[] permissions = requiresPermission.value();
LogicalOperator operator = requiresPermission.logical();
boolean hasPermission = false;
if (operator == LogicalOperator.AND) {
// 需要拥有所有权限
hasPermission = Arrays.stream(permissions)
.allMatch(permission -> authorizationService.hasPermission(currentUser, permission));
} else {
// 需要拥有任一权限
hasPermission = Arrays.stream(permissions)
.anyMatch(permission -> authorizationService.hasPermission(currentUser, permission));
}
if (!hasPermission) {
log.warn("用户 {} 尝试访问需要权限 {} 的方法 {}",
currentUser.getUsername(),
Arrays.toString(permissions),
joinPoint.getSignature().getName());
throw new AccessDeniedException("权限不足");
}
log.info("用户 {} 通过权限验证,访问方法 {}",
currentUser.getUsername(),
joinPoint.getSignature().getName());
}
/**
* 角色检查
*/
@Before("@annotation(requiresRole)")
public void checkRole(JoinPoint joinPoint, RequiresRole requiresRole) {
UserContext currentUser = authenticationService.getCurrentUser();
if (currentUser == null) {
throw new UnauthorizedException("用户未登录");
}
String[] roles = requiresRole.value();
LogicalOperator operator = requiresRole.logical();
boolean hasRole = false;
if (operator == LogicalOperator.AND) {
hasRole = Arrays.stream(roles)
.allMatch(role -> authorizationService.hasRole(currentUser, role));
} else {
hasRole = Arrays.stream(roles)
.anyMatch(role -> authorizationService.hasRole(currentUser, role));
}
if (!hasRole) {
throw new AccessDeniedException("角色权限不足");
}
}
/**
* 数据权限检查
*/
@Around("@annotation(dataPermission)")
public Object checkDataPermission(ProceedingJoinPoint joinPoint, DataPermission dataPermission) throws Throwable {
UserContext currentUser = authenticationService.getCurrentUser();
if (currentUser == null) {
throw new UnauthorizedException("用户未登录");
}
// 获取数据权限过滤条件
DataFilter dataFilter = authorizationService.getDataFilter(currentUser, dataPermission.entity());
// 修改查询参数,添加数据权限过滤
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof QueryCondition) {
QueryCondition condition = (QueryCondition) args[i];
condition.addFilter(dataFilter);
}
}
return joinPoint.proceed(args);
}
/**
* 操作审计
*/
@AfterReturning(pointcut = "@annotation(auditLog)", returning = "result")
public void auditOperation(JoinPoint joinPoint, AuditLog auditLog, Object result) {
UserContext currentUser = authenticationService.getCurrentUser();
AuditRecord record = AuditRecord.builder()
.userId(currentUser != null ? currentUser.getUserId() : null)
.username(currentUser != null ? currentUser.getUsername() : "anonymous")
.operation(auditLog.operation())
.module(auditLog.module())
.method(joinPoint.getSignature().getName())
.args(Arrays.toString(joinPoint.getArgs()))
.result(result != null ? result.toString() : null)
.timestamp(LocalDateTime.now())
.ipAddress(getClientIpAddress())
.build();
// 异步保存审计记录
auditService.saveAuditRecord(record);
log.info("操作审计: 用户 {} 执行 {} 操作",
record.getUsername(), record.getOperation());
}
private String getClientIpAddress() {
try {
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.currentRequestAttributes()).getRequest();
return getIpAddress(request);
} catch (Exception e) {
return "unknown";
}
}
private String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
/**
* 权限相关注解定义
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermission {
String[] value();
LogicalOperator logical() default LogicalOperator.AND;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresRole {
String[] value();
LogicalOperator logical() default LogicalOperator.AND;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataPermission {
String entity();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuditLog {
String operation();
String module() default "";
}
public enum LogicalOperator {
AND, OR
}/**
* 分布式事务切面
* 处理跨服务的事务一致性
*/
@Aspect
@Component
@Slf4j
public class DistributedTransactionAspect {
private final TransactionManager transactionManager;
private final MessageProducer messageProducer;
public DistributedTransactionAspect(TransactionManager transactionManager,
MessageProducer messageProducer) {
this.transactionManager = transactionManager;
this.messageProducer = messageProducer;
}
/**
* 分布式事务处理
*/
@Around("@annotation(distributedTransaction)")
public Object handleDistributedTransaction(ProceedingJoinPoint joinPoint,
DistributedTransaction distributedTransaction) throws Throwable {
String transactionId = generateTransactionId();
TransactionContext context = new TransactionContext(transactionId);
// 设置事务上下文
TransactionContextHolder.setContext(context);
try {
log.info("开始分布式事务: {}", transactionId);
// 执行本地事务
Object result = joinPoint.proceed();
// 发送事务消息
if (distributedTransaction.sendMessage()) {
TransactionMessage message = buildTransactionMessage(joinPoint, result, transactionId);
messageProducer.sendTransactionMessage(message);
}
// 提交分布式事务
transactionManager.commit(transactionId);
log.info("分布式事务提交成功: {}", transactionId);
return result;
} catch (Exception e) {
log.error("分布式事务执行失败: {}", transactionId, e);
try {
// 回滚分布式事务
transactionManager.rollback(transactionId);
log.info("分布式事务回滚成功: {}", transactionId);
} catch (Exception rollbackException) {
log.error("分布式事务回滚失败: {}", transactionId, rollbackException);
}
throw e;
} finally {
TransactionContextHolder.clear();
}
}
/**
* 本地事务重试
*/
@Around("@annotation(retryableTransaction)")
public Object retryTransaction(ProceedingJoinPoint joinPoint,
RetryableTransaction retryableTransaction) throws Throwable {
int maxRetries = retryableTransaction.maxRetries();
long delay = retryableTransaction.delay();
Class<? extends Exception>[] retryFor = retryableTransaction.retryFor();
Exception lastException = null;
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
return joinPoint.proceed();
} catch (Exception e) {
lastException = e;
// 检查是否为可重试异常
boolean shouldRetry = Arrays.stream(retryFor)
.anyMatch(exceptionClass -> exceptionClass.isInstance(e));
if (!shouldRetry || attempt == maxRetries) {
throw e;
}
log.warn("事务执行失败,第 {} 次重试,{}ms后重试: {}",
attempt, delay, e.getMessage());
Thread.sleep(delay);
}
}
throw lastException;
}
private String generateTransactionId() {
return "TXN_" + System.currentTimeMillis() + "_" +
UUID.randomUUID().toString().replace("-", "").substring(0, 8);
}
private TransactionMessage buildTransactionMessage(ProceedingJoinPoint joinPoint,
Object result, String transactionId) {
return TransactionMessage.builder()
.transactionId(transactionId)
.method(joinPoint.getSignature().getName())
.args(joinPoint.getArgs())
.result(result)
.timestamp(LocalDateTime.now())
.build();
}
}/**
* 统一异常处理切面
* 提供全局异常处理和错误恢复机制
*/
@Aspect
@Component
@Slf4j
public class ExceptionHandlingAspect {
private final NotificationService notificationService;
private final ErrorRecoveryService errorRecoveryService;
public ExceptionHandlingAspect(NotificationService notificationService,
ErrorRecoveryService errorRecoveryService) {
this.notificationService = notificationService;
this.errorRecoveryService = errorRecoveryService;
}
/**
* 业务异常处理
*/
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "exception")
public void handleBusinessException(JoinPoint joinPoint, Exception exception) {
String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getTarget().getClass().getSimpleName();
Object[] args = joinPoint.getArgs();
// 记录异常信息
log.error("业务异常 - 类: {}, 方法: {}, 参数: {}, 异常: {}",
className, methodName, Arrays.toString(args), exception.getMessage(), exception);
// 根据异常类型进行不同处理
if (exception instanceof BusinessException) {
handleBusinessException((BusinessException) exception, joinPoint);
} else if (exception instanceof SystemException) {
handleSystemException((SystemException) exception, joinPoint);
} else if (exception instanceof DataAccessException) {
handleDataAccessException((DataAccessException) exception, joinPoint);
} else {
handleUnknownException(exception, joinPoint);
}
}
/**
* 控制器异常处理
*/
@Around("execution(* com.example.controller.*.*(..))")
public Object handleControllerException(ProceedingJoinPoint joinPoint) throws Throwable {
try {
return joinPoint.proceed();
} catch (BusinessException e) {
log.warn("业务异常: {}", e.getMessage());
return ResponseEntity.badRequest().body(
ErrorResponse.builder()
.code(e.getCode())
.message(e.getMessage())
.timestamp(LocalDateTime.now())
.build()
);
} catch (SystemException e) {
log.error("系统异常", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
ErrorResponse.builder()
.code("SYSTEM_ERROR")
.message("系统内部错误")
.timestamp(LocalDateTime.now())
.build()
);
} catch (Exception e) {
log.error("未知异常", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
ErrorResponse.builder()
.code("UNKNOWN_ERROR")
.message("未知错误")
.timestamp(LocalDateTime.now())
.build()
);
}
}
/**
* 异常恢复处理
*/
@Around("@annotation(errorRecovery)")
public Object handleErrorRecovery(ProceedingJoinPoint joinPoint,
ErrorRecovery errorRecovery) throws Throwable {
try {
return joinPoint.proceed();
} catch (Exception e) {
log.warn("方法执行异常,尝试错误恢复: {}", e.getMessage());
// 执行错误恢复策略
RecoveryStrategy strategy = errorRecovery.strategy();
Object fallbackResult = null;
switch (strategy) {
case RETURN_DEFAULT:
fallbackResult = getDefaultValue(joinPoint.getSignature().getReturnType());
break;
case RETURN_CACHED:
fallbackResult = getCachedResult(joinPoint);
break;
case EXECUTE_FALLBACK:
fallbackResult = executeFallbackMethod(joinPoint, errorRecovery.fallbackMethod());
break;
case RETHROW:
default:
throw e;
}
log.info("错误恢复成功,返回: {}", fallbackResult);
return fallbackResult;
}
}
private void handleBusinessException(BusinessException exception, JoinPoint joinPoint) {
// 业务异常处理逻辑
if (exception.getLevel() == ErrorLevel.HIGH) {
notificationService.sendAlert("高级别业务异常", exception.getMessage());
}
}
private void handleSystemException(SystemException exception, JoinPoint joinPoint) {
// 系统异常处理逻辑
notificationService.sendAlert("系统异常", exception.getMessage());
// 尝试自动恢复
errorRecoveryService.attemptRecovery(exception);
}
private void handleDataAccessException(DataAccessException exception, JoinPoint joinPoint) {
// 数据访问异常处理逻辑
log.error("数据访问异常", exception);
// 检查数据库连接状态
errorRecoveryService.checkDatabaseConnection();
}
private void handleUnknownException(Exception exception, JoinPoint joinPoint) {
// 未知异常处理逻辑
notificationService.sendAlert("未知异常", exception.getMessage());
}
private Object getDefaultValue(Class<?> returnType) {
if (returnType == void.class || returnType == Void.class) {
return null;
} else if (returnType == boolean.class || returnType == Boolean.class) {
return false;
} else if (returnType.isPrimitive()) {
return 0;
} else if (Collection.class.isAssignableFrom(returnType)) {
return Collections.emptyList();
} else {
return null;
}
}
private Object getCachedResult(ProceedingJoinPoint joinPoint) {
// 从缓存获取结果的逻辑
String cacheKey = generateCacheKey(joinPoint);
return cacheManager.get(cacheKey);
}
private Object executeFallbackMethod(ProceedingJoinPoint joinPoint, String fallbackMethodName) {
try {
Method fallbackMethod = joinPoint.getTarget().getClass()
.getDeclaredMethod(fallbackMethodName, getParameterTypes(joinPoint));
fallbackMethod.setAccessible(true);
return fallbackMethod.invoke(joinPoint.getTarget(), joinPoint.getArgs());
} catch (Exception e) {
log.error("执行fallback方法失败", e);
return null;
}
}
private Class<?>[] getParameterTypes(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
Class<?>[] parameterTypes = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i] != null ? args[i].getClass() : Object.class;
}
return parameterTypes;
}
private String generateCacheKey(ProceedingJoinPoint joinPoint) {
return joinPoint.getSignature().getName() + ":" + Arrays.hashCode(joinPoint.getArgs());
}
}
/**
* 异常处理相关注解和类
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ErrorRecovery {
RecoveryStrategy strategy() default RecoveryStrategy.RETHROW;
String fallbackMethod() default "";
}
public enum RecoveryStrategy {
RETURN_DEFAULT, RETURN_CACHED, EXECUTE_FALLBACK, RETHROW
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedTransaction {
boolean sendMessage() default true;
String topic() default "";
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RetryableTransaction {
int maxRetries() default 3;
long delay() default 1000;
Class<? extends Exception>[] retryFor() default {Exception.class};
}/**
* 智能缓存切面
* 提供自动缓存、缓存更新、缓存失效等功能
*/
@Aspect
@Component
@Slf4j
public class CacheAspect {
private final CacheManager cacheManager;
private final CacheProperties cacheProperties;
public CacheAspect(CacheManager cacheManager, CacheProperties cacheProperties) {
this.cacheManager = cacheManager;
this.cacheProperties = cacheProperties;
}
/**
* 缓存查询结果
*/
@Around("@annotation(cacheable)")
public Object cacheResult(ProceedingJoinPoint joinPoint, Cacheable cacheable) throws Throwable {
String cacheKey = generateCacheKey(joinPoint, cacheable.key());
String cacheName = cacheable.value();
// 尝试从缓存获取
Object cachedResult = cacheManager.getCache(cacheName).get(cacheKey, Object.class);
if (cachedResult != null) {
log.debug("缓存命中: {} -> {}", cacheKey, cacheName);
return cachedResult;
}
// 执行方法获取结果
Object result = joinPoint.proceed();
// 缓存结果
if (result != null) {
Duration expireTime = Duration.ofSeconds(cacheable.expireTime());
cacheManager.getCache(cacheName).put(cacheKey, result);
// 设置过期时间
if (cacheable.expireTime() > 0) {
scheduleEviction(cacheName, cacheKey, expireTime);
}
log.debug("缓存存储: {} -> {} (过期时间: {}s)", cacheKey, cacheName, cacheable.expireTime());
}
return result;
}
/**
* 缓存更新
*/
@Around("@annotation(cacheEvict)")
public Object evictCache(ProceedingJoinPoint joinPoint, CacheEvict cacheEvict) throws Throwable {
Object result = joinPoint.proceed();
String cacheName = cacheEvict.value();
if (cacheEvict.allEntries()) {
// 清空整个缓存
cacheManager.getCache(cacheName).clear();
log.info("清空缓存: {}", cacheName);
} else {
// 清除特定缓存项
String cacheKey = generateCacheKey(joinPoint, cacheEvict.key());
cacheManager.getCache(cacheName).evict(cacheKey);
log.info("清除缓存: {} -> {}", cacheKey, cacheName);
}
return result;
}
/**
* 缓存更新
*/
@Around("@annotation(cachePut)")
public Object updateCache(ProceedingJoinPoint joinPoint, CachePut cachePut) throws Throwable {
Object result = joinPoint.proceed();
if (result != null) {
String cacheKey = generateCacheKey(joinPoint, cachePut.key());
String cacheName = cachePut.value();
cacheManager.getCache(cacheName).put(cacheKey, result);
log.debug("更新缓存: {} -> {}", cacheKey, cacheName);
}
return result;
}
/**
* 多级缓存处理
*/
@Around("@annotation(multiLevelCache)")
public Object handleMultiLevelCache(ProceedingJoinPoint joinPoint,
MultiLevelCache multiLevelCache) throws Throwable {
String cacheKey = generateCacheKey(joinPoint, multiLevelCache.key());
// L1缓存(本地缓存)
Object l1Result = getFromL1Cache(cacheKey);
if (l1Result != null) {
log.debug("L1缓存命中: {}", cacheKey);
return l1Result;
}
// L2缓存(分布式缓存)
Object l2Result = getFromL2Cache(cacheKey);
if (l2Result != null) {
log.debug("L2缓存命中: {}", cacheKey);
// 回写L1缓存
putToL1Cache(cacheKey, l2Result, multiLevelCache.l1ExpireTime());
return l2Result;
}
// 执行方法
Object result = joinPoint.proceed();
if (result != null) {
// 写入多级缓存
putToL1Cache(cacheKey, result, multiLevelCache.l1ExpireTime());
putToL2Cache(cacheKey, result, multiLevelCache.l2ExpireTime());
log.debug("多级缓存存储: {}", cacheKey);
}
return result;
}
private String generateCacheKey(ProceedingJoinPoint joinPoint, String keyExpression) {
if (StringUtils.hasText(keyExpression)) {
return evaluateKeyExpression(keyExpression, joinPoint);
}
// 默认键生成策略
StringBuilder keyBuilder = new StringBuilder();
keyBuilder.append(joinPoint.getTarget().getClass().getSimpleName())
.append(".")
.append(joinPoint.getSignature().getName());
Object[] args = joinPoint.getArgs();
if (args != null && args.length > 0) {
keyBuilder.append(":");
for (Object arg : args) {
keyBuilder.append(arg != null ? arg.hashCode() : "null").append(",");
}
}
return keyBuilder.toString();
}
private String evaluateKeyExpression(String expression, ProceedingJoinPoint joinPoint) {
// 简单的表达式求值,实际项目中可以使用SpEL
if (expression.startsWith("#")) {
String paramName = expression.substring(1);
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String[] paramNames = signature.getParameterNames();
Object[] args = joinPoint.getArgs();
for (int i = 0; i < paramNames.length; i++) {
if (paramNames[i].equals(paramName)) {
return args[i] != null ? args[i].toString() : "null";
}
}
}
return expression;
}
private void scheduleEviction(String cacheName, String cacheKey, Duration expireTime) {
// 实现缓存过期调度逻辑
CompletableFuture.delayedExecutor(expireTime.toMillis(), TimeUnit.MILLISECONDS)
.execute(() -> {
cacheManager.getCache(cacheName).evict(cacheKey);
log.debug("缓存过期清除: {} -> {}", cacheKey, cacheName);
});
}
private Object getFromL1Cache(String key) {
// L1缓存获取逻辑
return null;
}
private Object getFromL2Cache(String key) {
// L2缓存获取逻辑
return null;
}
private void putToL1Cache(String key, Object value, long expireTime) {
// L1缓存存储逻辑
}
private void putToL2Cache(String key, Object value, long expireTime) {
// L2缓存存储逻辑
}
}/**
* 数据校验切面
* 提供参数校验、业务规则校验等功能
*/
@Aspect
@Component
@Slf4j
public class ValidationAspect {
private final Validator validator;
private final BusinessRuleValidator businessRuleValidator;
public ValidationAspect(Validator validator, BusinessRuleValidator businessRuleValidator) {
this.validator = validator;
this.businessRuleValidator = businessRuleValidator;
}
/**
* 参数校验
*/
@Before("@annotation(validated)")
public void validateParameters(JoinPoint joinPoint, Validated validated) {
Object[] args = joinPoint.getArgs();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (arg == null) continue;
// JSR-303校验
Set<ConstraintViolation<Object>> violations = validator.validate(arg);
if (!violations.isEmpty()) {
StringBuilder errorMessage = new StringBuilder("参数校验失败: ");
for (ConstraintViolation<Object> violation : violations) {
errorMessage.append(violation.getPropertyPath())
.append(" ")
.append(violation.getMessage())
.append("; ");
}
throw new ValidationException(errorMessage.toString());
}
// 自定义校验注解处理
for (Annotation annotation : parameterAnnotations[i]) {
if (annotation instanceof NotEmpty) {
validateNotEmpty(arg, (NotEmpty) annotation);
} else if (annotation instanceof ValidEnum) {
validateEnum(arg, (ValidEnum) annotation);
} else if (annotation instanceof ValidDate) {
validateDate(arg, (ValidDate) annotation);
}
}
}
log.debug("参数校验通过: {}", signature.getName());
}
/**
* 业务规则校验
*/
@Before("@annotation(businessValidation)")
public void validateBusinessRules(JoinPoint joinPoint, BusinessValidation businessValidation) {
String[] rules = businessValidation.rules();
Object[] args = joinPoint.getArgs();
for (String rule : rules) {
ValidationResult result = businessRuleValidator.validate(rule, args);
if (!result.isValid()) {
log.warn("业务规则校验失败: {} - {}", rule, result.getMessage());
throw new BusinessValidationException(result.getMessage());
}
}
log.debug("业务规则校验通过: {}", Arrays.toString(rules));
}
/**
* 返回值校验
*/
@AfterReturning(pointcut = "@annotation(validateResult)", returning = "result")
public void validateResult(JoinPoint joinPoint, ValidateResult validateResult, Object result) {
if (result == null && !validateResult.allowNull()) {
throw new ValidationException("返回值不能为空");
}
if (result != null) {
Set<ConstraintViolation<Object>> violations = validator.validate(result);
if (!violations.isEmpty()) {
StringBuilder errorMessage = new StringBuilder("返回值校验失败: ");
for (ConstraintViolation<Object> violation : violations) {
errorMessage.append(violation.getPropertyPath())
.append(" ")
.append(violation.getMessage())
.append("; ");
}
throw new ValidationException(errorMessage.toString());
}
}
log.debug("返回值校验通过");
}
/**
* 数据一致性校验
*/
@Around("@annotation(consistencyCheck)")
public Object checkDataConsistency(ProceedingJoinPoint joinPoint,
ConsistencyCheck consistencyCheck) throws Throwable {
// 执行前检查
if (consistencyCheck.checkBefore()) {
performConsistencyCheck(joinPoint, "BEFORE");
}
Object result = joinPoint.proceed();
// 执行后检查
if (consistencyCheck.checkAfter()) {
performConsistencyCheck(joinPoint, "AFTER");
}
return result;
}
private void validateNotEmpty(Object arg, NotEmpty notEmpty) {
if (arg instanceof String && ((String) arg).trim().isEmpty()) {
throw new ValidationException(notEmpty.message());
} else if (arg instanceof Collection && ((Collection<?>) arg).isEmpty()) {
throw new ValidationException(notEmpty.message());
}
}
private void validateEnum(Object arg, ValidEnum validEnum) {
if (arg instanceof String) {
String value = (String) arg;
String[] allowedValues = validEnum.values();
if (!Arrays.asList(allowedValues).contains(value)) {
throw new ValidationException("枚举值无效: " + value);
}
}
}
private void validateDate(Object arg, ValidDate validDate) {
if (arg instanceof LocalDate) {
LocalDate date = (LocalDate) arg;
LocalDate now = LocalDate.now();
if (validDate.future() && !date.isAfter(now)) {
throw new ValidationException("日期必须是未来时间");
}
if (validDate.past() && !date.isBefore(now)) {
throw new ValidationException("日期必须是过去时间");
}
}
}
private void performConsistencyCheck(ProceedingJoinPoint joinPoint, String phase) {
log.info("执行数据一致性检查: {} - {}", phase, joinPoint.getSignature().getName());
// 实现具体的一致性检查逻辑
}
}
/**
* 校验相关注解定义
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BusinessValidation {
String[] rules();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidateResult {
boolean allowNull() default false;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ConsistencyCheck {
boolean checkBefore() default true;
boolean checkAfter() default true;
}
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotEmpty {
String message() default "参数不能为空";
}
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidEnum {
String[] values();
}
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidDate {
boolean future() default false;
boolean past() default false;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MultiLevelCache {
String key() default "";
long l1ExpireTime() default 300; // 5分钟
long l2ExpireTime() default 3600; // 1小时
}/**
* 切面优先级演示
* 展示如何控制多个切面的执行顺序
*/
// 最高优先级 - 安全检查切面
@Aspect
@Component
@Order(1)
@Slf4j
public class SecurityCheckAspect {
@Before("execution(* com.example.service.*.*(..))")
public void securityCheck(JoinPoint joinPoint) {
log.info("1. 执行安全检查 - {}", joinPoint.getSignature().getName());
}
}
// 第二优先级 - 参数校验切面
@Aspect
@Component
@Order(2)
@Slf4j
public class ParameterValidationAspect {
@Before("execution(* com.example.service.*.*(..))")
public void validateParameters(JoinPoint joinPoint) {
log.info("2. 执行参数校验 - {}", joinPoint.getSignature().getName());
}
}
// 第三优先级 - 事务管理切面
@Aspect
@Component
@Order(3)
@Slf4j
public class TransactionAspect {
@Before("execution(* com.example.service.*.*(..))")
public void beginTransaction(JoinPoint joinPoint) {
log.info("3. 开始事务 - {}", joinPoint.getSignature().getName());
}
@After("execution(* com.example.service.*.*(..))")
public void endTransaction(JoinPoint joinPoint) {
log.info("3. 结束事务 - {}", joinPoint.getSignature().getName());
}
}
// 第四优先级 - 日志记录切面
@Aspect
@Component
@Order(4)
@Slf4j
public class LoggingOrderAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
log.info("4. 记录方法开始 - {}", joinPoint.getSignature().getName());
}
@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
log.info("4. 记录方法结束 - {}", joinPoint.getSignature().getName());
}
}
/**
* 切面执行顺序管理器
*/
@Component
public class AspectOrderManager {
/**
* 动态调整切面优先级
*/
public void adjustAspectOrder(String aspectName, int newOrder) {
// 实现动态调整切面优先级的逻辑
log.info("调整切面 {} 的优先级为 {}", aspectName, newOrder);
}
/**
* 获取切面执行链
*/
public List<String> getAspectChain(Method method) {
// 返回指定方法的切面执行链
return Arrays.asList("SecurityCheckAspect", "ParameterValidationAspect",
"TransactionAspect", "LoggingOrderAspect");
}
}/**
* 条件化切面执行
* 根据不同条件决定是否执行切面逻辑
*/
@Aspect
@Component
@Slf4j
public class ConditionalAspect {
private final Environment environment;
private final FeatureToggleService featureToggleService;
public ConditionalAspect(Environment environment, FeatureToggleService featureToggleService) {
this.environment = environment;
this.featureToggleService = featureToggleService;
}
/**
* 基于环境的条件执行
*/
@Around("@annotation(environmentSpecific)")
public Object executeByEnvironment(ProceedingJoinPoint joinPoint,
EnvironmentSpecific environmentSpecific) throws Throwable {
String[] activeProfiles = environment.getActiveProfiles();
String[] targetEnvironments = environmentSpecific.environments();
boolean shouldExecute = Arrays.stream(activeProfiles)
.anyMatch(profile -> Arrays.asList(targetEnvironments).contains(profile));
if (shouldExecute) {
log.info("环境匹配,执行切面逻辑: {}", Arrays.toString(targetEnvironments));
return executeWithEnvironmentLogic(joinPoint, environmentSpecific);
} else {
log.debug("环境不匹配,跳过切面逻辑");
return joinPoint.proceed();
}
}
/**
* 基于功能开关的条件执行
*/
@Around("@annotation(featureToggle)")
public Object executeByFeatureToggle(ProceedingJoinPoint joinPoint,
FeatureToggle featureToggle) throws Throwable {
String featureName = featureToggle.value();
if (featureToggleService.isEnabled(featureName)) {
log.info("功能开关 {} 已启用,执行切面逻辑", featureName);
return executeWithFeatureLogic(joinPoint, featureToggle);
} else {
log.debug("功能开关 {} 未启用,跳过切面逻辑", featureName);
return joinPoint.proceed();
}
}
/**
* 基于时间的条件执行
*/
@Around("@annotation(timeBasedExecution)")
public Object executeByTime(ProceedingJoinPoint joinPoint,
TimeBasedExecution timeBasedExecution) throws Throwable {
LocalTime now = LocalTime.now();
LocalTime startTime = LocalTime.parse(timeBasedExecution.startTime());
LocalTime endTime = LocalTime.parse(timeBasedExecution.endTime());
if (now.isAfter(startTime) && now.isBefore(endTime)) {
log.info("时间范围内 ({}-{}),执行切面逻辑", startTime, endTime);
return executeWithTimeLogic(joinPoint, timeBasedExecution);
} else {
log.debug("时间范围外,跳过切面逻辑");
return joinPoint.proceed();
}
}
/**
* 基于用户角色的条件执行
*/
@Around("@annotation(roleBasedExecution)")
public Object executeByRole(ProceedingJoinPoint joinPoint,
RoleBasedExecution roleBasedExecution) throws Throwable {
UserContext currentUser = getCurrentUser();
if (currentUser == null) {
return joinPoint.proceed();
}
String[] requiredRoles = roleBasedExecution.roles();
boolean hasRequiredRole = Arrays.stream(requiredRoles)
.anyMatch(role -> currentUser.hasRole(role));
if (hasRequiredRole) {
log.info("用户角色匹配,执行切面逻辑: {}", Arrays.toString(requiredRoles));
return executeWithRoleLogic(joinPoint, roleBasedExecution);
} else {
log.debug("用户角色不匹配,跳过切面逻辑");
return joinPoint.proceed();
}
}
private Object executeWithEnvironmentLogic(ProceedingJoinPoint joinPoint,
EnvironmentSpecific environmentSpecific) throws Throwable {
// 环境特定的切面逻辑
return joinPoint.proceed();
}
private Object executeWithFeatureLogic(ProceedingJoinPoint joinPoint,
FeatureToggle featureToggle) throws Throwable {
// 功能开关相关的切面逻辑
return joinPoint.proceed();
}
private Object executeWithTimeLogic(ProceedingJoinPoint joinPoint,
TimeBasedExecution timeBasedExecution) throws Throwable {
// 时间相关的切面逻辑
return joinPoint.proceed();
}
private Object executeWithRoleLogic(ProceedingJoinPoint joinPoint,
RoleBasedExecution roleBasedExecution) throws Throwable {
// 角色相关的切面逻辑
return joinPoint.proceed();
}
private UserContext getCurrentUser() {
// 获取当前用户上下文
return null;
}
}
/**
* 条件执行相关注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnvironmentSpecific {
String[] environments() default {"dev", "test"};
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FeatureToggle {
String value();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeBasedExecution {
String startTime() default "09:00:00";
String endTime() default "18:00:00";
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RoleBasedExecution {
String[] roles();
}/**
* 动态切面管理器
* 支持运行时添加、移除和修改切面
*/
@Component
@Slf4j
public class DynamicAspectManager {
private final ApplicationContext applicationContext;
private final ConfigurableListableBeanFactory beanFactory;
private final Map<String, Object> dynamicAspects = new ConcurrentHashMap<>();
public DynamicAspectManager(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.beanFactory = (ConfigurableListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
}
/**
* 动态添加切面
*/
public void addAspect(String aspectName, Object aspectInstance) {
try {
// 注册切面Bean
beanFactory.registerSingleton(aspectName, aspectInstance);
dynamicAspects.put(aspectName, aspectInstance);
log.info("动态添加切面成功: {}", aspectName);
} catch (Exception e) {
log.error("动态添加切面失败: {}", aspectName, e);
throw new RuntimeException("Failed to add dynamic aspect: " + aspectName, e);
}
}
/**
* 动态移除切面
*/
public void removeAspect(String aspectName) {
try {
if (dynamicAspects.containsKey(aspectName)) {
// 从容器中移除Bean
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory).removeBeanDefinition(aspectName);
}
dynamicAspects.remove(aspectName);
log.info("动态移除切面成功: {}", aspectName);
}
} catch (Exception e) {
log.error("动态移除切面失败: {}", aspectName, e);
throw new RuntimeException("Failed to remove dynamic aspect: " + aspectName, e);
}
}
/**
* 获取所有动态切面
*/
public Map<String, Object> getAllDynamicAspects() {
return new HashMap<>(dynamicAspects);
}
/**
* 检查切面是否存在
*/
public boolean hasAspect(String aspectName) {
return dynamicAspects.containsKey(aspectName);
}
}
/**
* 可配置的动态切面
*/
@Slf4j
public class ConfigurableAspect {
private final AspectConfiguration configuration;
private final List<AdviceDefinition> adviceDefinitions;
public ConfigurableAspect(AspectConfiguration configuration) {
this.configuration = configuration;
this.adviceDefinitions = new ArrayList<>();
}
/**
* 添加通知定义
*/
public void addAdvice(AdviceDefinition adviceDefinition) {
adviceDefinitions.add(adviceDefinition);
log.info("添加通知定义: {}", adviceDefinition.getName());
}
/**
* 执行前置通知
*/
public void executeBefore(JoinPoint joinPoint) {
adviceDefinitions.stream()
.filter(advice -> advice.getType() == AdviceType.BEFORE)
.forEach(advice -> {
try {
advice.execute(joinPoint, null);
} catch (Exception e) {
log.error("执行前置通知失败: {}", advice.getName(), e);
}
});
}
/**
* 执行后置通知
*/
public void executeAfter(JoinPoint joinPoint) {
adviceDefinitions.stream()
.filter(advice -> advice.getType() == AdviceType.AFTER)
.forEach(advice -> {
try {
advice.execute(joinPoint, null);
} catch (Exception e) {
log.error("执行后置通知失败: {}", advice.getName(), e);
}
});
}
/**
* 执行环绕通知
*/
public Object executeAround(ProceedingJoinPoint joinPoint) throws Throwable {
List<AdviceDefinition> aroundAdvices = adviceDefinitions.stream()
.filter(advice -> advice.getType() == AdviceType.AROUND)
.collect(Collectors.toList());
if (aroundAdvices.isEmpty()) {
return joinPoint.proceed();
}
return executeAroundChain(joinPoint, aroundAdvices, 0);
}
private Object executeAroundChain(ProceedingJoinPoint joinPoint,
List<AdviceDefinition> advices,
int index) throws Throwable {
if (index >= advices.size()) {
return joinPoint.proceed();
}
AdviceDefinition currentAdvice = advices.get(index);
return currentAdvice.executeAround(joinPoint, () -> {
try {
return executeAroundChain(joinPoint, advices, index + 1);
} catch (Throwable e) {
throw new RuntimeException(e);
}
});
}
}
/**
* 通知定义
*/
public class AdviceDefinition {
private final String name;
private final AdviceType type;
private final String pointcut;
private final AdviceExecutor executor;
public AdviceDefinition(String name, AdviceType type, String pointcut, AdviceExecutor executor) {
this.name = name;
this.type = type;
this.pointcut = pointcut;
this.executor = executor;
}
public void execute(JoinPoint joinPoint, Object result) {
executor.execute(joinPoint, result);
}
public Object executeAround(ProceedingJoinPoint joinPoint, Supplier<Object> proceed) {
return executor.executeAround(joinPoint, proceed);
}
// Getters
public String getName() { return name; }
public AdviceType getType() { return type; }
public String getPointcut() { return pointcut; }
}
/**
* 通知执行器接口
*/
@FunctionalInterface
public interface AdviceExecutor {
void execute(JoinPoint joinPoint, Object result);
default Object executeAround(ProceedingJoinPoint joinPoint, Supplier<Object> proceed) {
execute(joinPoint, null);
Object result = proceed.get();
execute(joinPoint, result);
return result;
}
}
/**
* 通知类型枚举
*/
public enum AdviceType {
BEFORE, AFTER, AFTER_RETURNING, AFTER_THROWING, AROUND
}
/**
* 切面配置
*/
public class AspectConfiguration {
private String name;
private int order;
private boolean enabled;
private Map<String, Object> properties;
// 构造函数和getter/setter方法
public AspectConfiguration(String name) {
this.name = name;
this.order = 0;
this.enabled = true;
this.properties = new HashMap<>();
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getOrder() { return order; }
public void setOrder(int order) { this.order = order; }
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
public Map<String, Object> getProperties() { return properties; }
public void setProperties(Map<String, Object> properties) { this.properties = properties; }
}/**
* 切面配置热更新管理器
*/
@Component
@Slf4j
public class AspectConfigurationManager {
private final DynamicAspectManager dynamicAspectManager;
private final ApplicationEventPublisher eventPublisher;
private final Map<String, AspectConfiguration> configurations = new ConcurrentHashMap<>();
public AspectConfigurationManager(DynamicAspectManager dynamicAspectManager,
ApplicationEventPublisher eventPublisher) {
this.dynamicAspectManager = dynamicAspectManager;
this.eventPublisher = eventPublisher;
}
/**
* 更新切面配置
*/
public void updateConfiguration(String aspectName, AspectConfiguration newConfig) {
AspectConfiguration oldConfig = configurations.get(aspectName);
configurations.put(aspectName, newConfig);
// 发布配置更新事件
eventPublisher.publishEvent(new AspectConfigurationChangedEvent(
aspectName, oldConfig, newConfig));
// 重新加载切面
reloadAspect(aspectName, newConfig);
log.info("切面配置更新完成: {}", aspectName);
}
/**
* 重新加载切面
*/
private void reloadAspect(String aspectName, AspectConfiguration config) {
try {
// 移除旧切面
if (dynamicAspectManager.hasAspect(aspectName)) {
dynamicAspectManager.removeAspect(aspectName);
}
// 创建新切面实例
if (config.isEnabled()) {
ConfigurableAspect newAspect = createAspectFromConfiguration(config);
dynamicAspectManager.addAspect(aspectName, newAspect);
}
} catch (Exception e) {
log.error("重新加载切面失败: {}", aspectName, e);
throw new RuntimeException("Failed to reload aspect: " + aspectName, e);
}
}
/**
* 从配置创建切面实例
*/
private ConfigurableAspect createAspectFromConfiguration(AspectConfiguration config) {
ConfigurableAspect aspect = new ConfigurableAspect(config);
// 根据配置添加通知
Map<String, Object> properties = config.getProperties();
if (properties.containsKey("beforeAdvice")) {
aspect.addAdvice(createAdviceFromProperty("beforeAdvice",
AdviceType.BEFORE, (String) properties.get("beforeAdvice")));
}
if (properties.containsKey("afterAdvice")) {
aspect.addAdvice(createAdviceFromProperty("afterAdvice",
AdviceType.AFTER, (String) properties.get("afterAdvice")));
}
if (properties.containsKey("aroundAdvice")) {
aspect.addAdvice(createAdviceFromProperty("aroundAdvice",
AdviceType.AROUND, (String) properties.get("aroundAdvice")));
}
return aspect;
}
/**
* 从属性创建通知定义
*/
private AdviceDefinition createAdviceFromProperty(String name, AdviceType type, String config) {
// 解析配置字符串,创建通知执行器
AdviceExecutor executor = createExecutorFromConfig(config);
return new AdviceDefinition(name, type, "*", executor);
}
/**
* 从配置创建执行器
*/
private AdviceExecutor createExecutorFromConfig(String config) {
return (joinPoint, result) -> {
log.info("执行配置化通知: {} - {}", config, joinPoint.getSignature().getName());
// 根据配置执行相应的逻辑
};
}
/**
* 获取配置
*/
public AspectConfiguration getConfiguration(String aspectName) {
return configurations.get(aspectName);
}
/**
* 获取所有配置
*/
public Map<String, AspectConfiguration> getAllConfigurations() {
return new HashMap<>(configurations);
}
}
/**
* 切面配置变更事件
*/
public class AspectConfigurationChangedEvent extends ApplicationEvent {
private final String aspectName;
private final AspectConfiguration oldConfiguration;
private final AspectConfiguration newConfiguration;
public AspectConfigurationChangedEvent(Object source, String aspectName,
AspectConfiguration oldConfiguration,
AspectConfiguration newConfiguration) {
super(source);
this.aspectName = aspectName;
this.oldConfiguration = oldConfiguration;
this.newConfiguration = newConfiguration;
}
// Getters
public String getAspectName() { return aspectName; }
public AspectConfiguration getOldConfiguration() { return oldConfiguration; }
public AspectConfiguration getNewConfiguration() { return newConfiguration; }
}
/**
* 配置变更监听器
*/
@Component
@Slf4j
public class AspectConfigurationListener {
@EventListener
public void handleConfigurationChanged(AspectConfigurationChangedEvent event) {
log.info("切面配置发生变更: {} -> {}",
event.getAspectName(), event.getNewConfiguration().getName());
// 执行配置变更后的处理逻辑
performPostConfigurationChange(event);
}
private void performPostConfigurationChange(AspectConfigurationChangedEvent event) {
// 清理缓存、更新监控指标等
log.debug("执行配置变更后处理: {}", event.getAspectName());
}
}/**
* 高性能切面设计示例
* 展示切面开发的最佳实践
*/
@Aspect
@Component
@Slf4j
public class HighPerformanceAspect {
private final MetricRegistry metricRegistry;
private final ThreadLocal<ExecutionContext> contextHolder = new ThreadLocal<>();
// 使用缓存避免重复计算
private final LoadingCache<String, Boolean> pointcutCache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(Duration.ofMinutes(10))
.build(this::evaluatePointcut);
public HighPerformanceAspect(MetricRegistry metricRegistry) {
this.metricRegistry = metricRegistry;
}
/**
* 高效的切点表达式
* 使用具体的包名和类名,避免过于宽泛的匹配
*/
@Pointcut("execution(* com.example.service..*Service.*(..))")
public void serviceLayer() {}
@Pointcut("@annotation(com.example.annotation.Monitored)")
public void monitoredMethods() {}
/**
* 组合切点,提高匹配效率
*/
@Pointcut("serviceLayer() && monitoredMethods()")
public void monitoredServiceMethods() {}
/**
* 高性能环绕通知
*/
@Around("monitoredServiceMethods()")
public Object monitorExecution(ProceedingJoinPoint joinPoint) throws Throwable {
String methodSignature = joinPoint.getSignature().toLongString();
// 使用缓存检查是否需要监控
if (!pointcutCache.get(methodSignature)) {
return joinPoint.proceed();
}
ExecutionContext context = new ExecutionContext(methodSignature);
contextHolder.set(context);
Timer.Sample sample = Timer.start(metricRegistry);
try {
Object result = joinPoint.proceed();
context.setSuccess(true);
return result;
} catch (Exception e) {
context.setSuccess(false);
context.setException(e);
throw e;
} finally {
sample.stop(Timer.builder("method.execution")
.tag("method", methodSignature)
.tag("success", String.valueOf(context.isSuccess()))
.register(metricRegistry));
contextHolder.remove();
}
}
/**
* 异步日志记录,避免阻塞主线程
*/
@AfterReturning(pointcut = "monitoredServiceMethods()", returning = "result")
public void logSuccess(JoinPoint joinPoint, Object result) {
CompletableFuture.runAsync(() -> {
ExecutionContext context = contextHolder.get();
if (context != null && context.isSuccess()) {
log.info("方法执行成功: {} - 耗时: {}ms",
context.getMethodSignature(), context.getExecutionTime());
}
});
}
/**
* 切点评估方法
*/
private Boolean evaluatePointcut(String methodSignature) {
// 实现切点评估逻辑
return methodSignature.contains("Service") && !methodSignature.contains("Internal");
}
/**
* 执行上下文
*/
private static class ExecutionContext {
private final String methodSignature;
private final long startTime;
private boolean success;
private Exception exception;
public ExecutionContext(String methodSignature) {
this.methodSignature = methodSignature;
this.startTime = System.currentTimeMillis();
}
public long getExecutionTime() {
return System.currentTimeMillis() - startTime;
}
// Getters and setters
public String getMethodSignature() { return methodSignature; }
public boolean isSuccess() { return success; }
public void setSuccess(boolean success) { this.success = success; }
public Exception getException() { return exception; }
public void setException(Exception exception) { this.exception = exception; }
}
}
/**
* 资源管理切面
* 展示资源的正确获取和释放
*/
@Aspect
@Component
@Slf4j
public class ResourceManagementAspect {
private final ResourcePool resourcePool;
private final Map<String, Resource> threadResources = new ConcurrentHashMap<>();
public ResourceManagementAspect(ResourcePool resourcePool) {
this.resourcePool = resourcePool;
}
/**
* 资源管理环绕通知
*/
@Around("@annotation(resourceRequired)")
public Object manageResource(ProceedingJoinPoint joinPoint,
ResourceRequired resourceRequired) throws Throwable {
String resourceType = resourceRequired.type();
String threadId = Thread.currentThread().getName();
String resourceKey = threadId + ":" + resourceType;
Resource resource = null;
try {
// 获取资源
resource = resourcePool.acquire(resourceType, resourceRequired.timeout());
threadResources.put(resourceKey, resource);
log.debug("获取资源成功: {} - {}", resourceType, threadId);
// 执行业务方法
return joinPoint.proceed();
} catch (ResourceUnavailableException e) {
log.warn("资源获取失败: {} - {}", resourceType, e.getMessage());
if (resourceRequired.fallbackEnabled()) {
return executeFallback(joinPoint, resourceRequired);
} else {
throw e;
}
} finally {
// 释放资源
if (resource != null) {
try {
resourcePool.release(resource);
threadResources.remove(resourceKey);
log.debug("释放资源成功: {} - {}", resourceType, threadId);
} catch (Exception e) {
log.error("释放资源失败: {} - {}", resourceType, e.getMessage());
}
}
}
}
/**
* 执行降级逻辑
*/
private Object executeFallback(ProceedingJoinPoint joinPoint, ResourceRequired resourceRequired) {
String fallbackMethod = resourceRequired.fallbackMethod();
if (StringUtils.hasText(fallbackMethod)) {
try {
Method method = joinPoint.getTarget().getClass()
.getDeclaredMethod(fallbackMethod, getParameterTypes(joinPoint));
method.setAccessible(true);
return method.invoke(joinPoint.getTarget(), joinPoint.getArgs());
} catch (Exception e) {
log.error("执行降级方法失败: {}", fallbackMethod, e);
}
}
return getDefaultResult(joinPoint);
}
private Class<?>[] getParameterTypes(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
Class<?>[] types = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
types[i] = args[i] != null ? args[i].getClass() : Object.class;
}
return types;
}
private Object getDefaultResult(ProceedingJoinPoint joinPoint) {
Class<?> returnType = ((MethodSignature) joinPoint.getSignature()).getReturnType();
if (returnType == void.class) {
return null;
} else if (returnType == boolean.class) {
return false;
} else if (returnType.isPrimitive()) {
return 0;
} else if (Collection.class.isAssignableFrom(returnType)) {
return Collections.emptyList();
} else {
return null;
}
}
}
/**
* 资源需求注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResourceRequired {
String type();
long timeout() default 5000;
boolean fallbackEnabled() default true;
String fallbackMethod() default "";
}
/**
* 监控注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Monitored {
String value() default "";
boolean async() default false;
}/**
* 分布式追踪切面
* 在微服务环境中实现请求链路追踪
*/
@Aspect
@Component
@Slf4j
public class DistributedTracingAspect {
private final TraceContext traceContext;
private final SpanBuilder spanBuilder;
private final MetricCollector metricCollector;
public DistributedTracingAspect(TraceContext traceContext,
SpanBuilder spanBuilder,
MetricCollector metricCollector) {
this.traceContext = traceContext;
this.spanBuilder = spanBuilder;
this.metricCollector = metricCollector;
}
/**
* 服务间调用追踪
*/
@Around("@annotation(traceableService)")
public Object traceServiceCall(ProceedingJoinPoint joinPoint,
TraceableService traceableService) throws Throwable {
String serviceName = traceableService.value();
String operationName = joinPoint.getSignature().getName();
// 创建或继续Span
Span span = spanBuilder.createSpan(serviceName, operationName);
try {
// 设置Span标签
span.setTag("service.name", serviceName);
span.setTag("method.name", operationName);
span.setTag("thread.name", Thread.currentThread().getName());
// 记录请求参数
if (traceableService.logParameters()) {
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
span.setTag("param." + i, String.valueOf(args[i]));
}
}
// 执行业务方法
Object result = joinPoint.proceed();
// 记录响应信息
span.setTag("success", "true");
if (traceableService.logResult() && result != null) {
span.setTag("result.type", result.getClass().getSimpleName());
}
return result;
} catch (Exception e) {
// 记录异常信息
span.setTag("success", "false");
span.setTag("error.class", e.getClass().getSimpleName());
span.setTag("error.message", e.getMessage());
// 记录异常堆栈
span.log("exception", ExceptionUtils.getStackTrace(e));
throw e;
} finally {
// 完成Span
span.finish();
// 收集指标
metricCollector.recordServiceCall(serviceName, operationName, span.getDuration());
}
}
/**
* HTTP请求追踪
*/
@Around("@annotation(traceableHttp)")
public Object traceHttpRequest(ProceedingJoinPoint joinPoint,
TraceableHttp traceableHttp) throws Throwable {
HttpServletRequest request = getCurrentHttpRequest();
if (request == null) {
return joinPoint.proceed();
}
String traceId = extractTraceId(request);
String spanId = generateSpanId();
// 设置追踪上下文
traceContext.setTraceId(traceId);
traceContext.setSpanId(spanId);
Span span = spanBuilder.createSpan("http-request", request.getRequestURI());
try {
// 记录HTTP信息
span.setTag("http.method", request.getMethod());
span.setTag("http.url", request.getRequestURL().toString());
span.setTag("http.user_agent", request.getHeader("User-Agent"));
span.setTag("http.remote_addr", getClientIpAddress(request));
Object result = joinPoint.proceed();
// 记录响应状态
HttpServletResponse response = getCurrentHttpResponse();
if (response != null) {
span.setTag("http.status_code", String.valueOf(response.getStatus()));
}
return result;
} catch (Exception e) {
span.setTag("http.status_code", "500");
span.setTag("error", "true");
throw e;
} finally {
span.finish();
traceContext.clear();
}
}
/**
* 数据库操作追踪
*/
@Around("@annotation(traceableDatabase)")
public Object traceDatabaseOperation(ProceedingJoinPoint joinPoint,
TraceableDatabase traceableDatabase) throws Throwable {
String operation = traceableDatabase.operation();
String table = traceableDatabase.table();
Span span = spanBuilder.createSpan("database", operation);
try {
span.setTag("db.type", "mysql");
span.setTag("db.operation", operation);
span.setTag("db.table", table);
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - startTime;
span.setTag("db.duration", String.valueOf(duration));
// 记录影响行数(如果适用)
if (result instanceof Number) {
span.setTag("db.rows_affected", result.toString());
}
return result;
} catch (Exception e) {
span.setTag("db.error", "true");
span.setTag("db.error_message", e.getMessage());
throw e;
} finally {
span.finish();
}
}
private String extractTraceId(HttpServletRequest request) {
String traceId = request.getHeader("X-Trace-Id");
return traceId != null ? traceId : generateTraceId();
}
private String generateTraceId() {
return UUID.randomUUID().toString().replace("-", "");
}
private String generateSpanId() {
return Long.toHexString(System.nanoTime());
}
private String getClientIpAddress(HttpServletRequest request) {
String xForwardedFor = request.getHeader("X-Forwarded-For");
if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
return xForwardedFor.split(",")[0].trim();
}
String xRealIp = request.getHeader("X-Real-IP");
if (xRealIp != null && !xRealIp.isEmpty()) {
return xRealIp;
}
return request.getRemoteAddr();
}
private HttpServletRequest getCurrentHttpRequest() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes instanceof ServletRequestAttributes) {
return ((ServletRequestAttributes) requestAttributes).getRequest();
}
return null;
}
private HttpServletResponse getCurrentHttpResponse() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes instanceof ServletRequestAttributes) {
return ((ServletRequestAttributes) requestAttributes).getResponse();
}
return null;
}
}
/**
* 追踪相关注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TraceableService {
String value();
boolean logParameters() default false;
boolean logResult() default false;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TraceableHttp {
boolean logHeaders() default false;
boolean logBody() default false;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TraceableDatabase {
String operation();
String table() default "";
}/**
* 服务熔断与降级切面
* 实现微服务的容错机制
*/
@Aspect
@Component
@Slf4j
public class CircuitBreakerAspect {
private final CircuitBreakerRegistry circuitBreakerRegistry;
private final FallbackMethodResolver fallbackMethodResolver;
private final MetricRegistry metricRegistry;
public CircuitBreakerAspect(CircuitBreakerRegistry circuitBreakerRegistry,
FallbackMethodResolver fallbackMethodResolver,
MetricRegistry metricRegistry) {
this.circuitBreakerRegistry = circuitBreakerRegistry;
this.fallbackMethodResolver = fallbackMethodResolver;
this.metricRegistry = metricRegistry;
}
/**
* 熔断器环绕通知
*/
@Around("@annotation(circuitBreaker)")
public Object handleCircuitBreaker(ProceedingJoinPoint joinPoint,
CircuitBreaker circuitBreaker) throws Throwable {
String serviceName = circuitBreaker.name();
io.github.resilience4j.circuitbreaker.CircuitBreaker cb =
circuitBreakerRegistry.circuitBreaker(serviceName);
// 检查熔断器状态
if (cb.getState() == io.github.resilience4j.circuitbreaker.CircuitBreaker.State.OPEN) {
log.warn("熔断器开启,执行降级逻辑: {}", serviceName);
return executeFallback(joinPoint, circuitBreaker);
}
Timer.Sample sample = Timer.start(metricRegistry);
try {
// 执行业务方法
Object result = cb.executeSupplier(() -> {
try {
return joinPoint.proceed();
} catch (Throwable e) {
throw new RuntimeException(e);
}
});
// 记录成功指标
sample.stop(Timer.builder("circuit.breaker.call")
.tag("service", serviceName)
.tag("result", "success")
.register(metricRegistry));
return result;
} catch (Exception e) {
// 记录失败指标
sample.stop(Timer.builder("circuit.breaker.call")
.tag("service", serviceName)
.tag("result", "failure")
.register(metricRegistry));
log.error("服务调用失败,可能触发熔断: {} - {}", serviceName, e.getMessage());
// 执行降级逻辑
if (circuitBreaker.fallbackEnabled()) {
return executeFallback(joinPoint, circuitBreaker);
} else {
throw e;
}
}
}
/**
* 重试机制
*/
@Around("@annotation(retryable)")
public Object handleRetry(ProceedingJoinPoint joinPoint,
Retryable retryable) throws Throwable {
String operationName = joinPoint.getSignature().getName();
int maxAttempts = retryable.maxAttempts();
long delay = retryable.delay();
Exception lastException = null;
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
try {
log.debug("执行重试,第{}次尝试: {}", attempt, operationName);
Object result = joinPoint.proceed();
if (attempt > 1) {
log.info("重试成功,第{}次尝试: {}", attempt, operationName);
}
return result;
} catch (Exception e) {
lastException = e;
if (attempt == maxAttempts) {
log.error("重试失败,已达到最大重试次数: {} - {}", operationName, maxAttempts);
break;
}
if (shouldRetry(e, retryable.retryFor())) {
log.warn("第{}次尝试失败,{}ms后重试: {} - {}",
attempt, delay, operationName, e.getMessage());
try {
Thread.sleep(delay);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("重试被中断", ie);
}
// 指数退避
if (retryable.exponentialBackoff()) {
delay *= 2;
}
} else {
log.warn("异常不符合重试条件: {} - {}", operationName, e.getClass().getSimpleName());
break;
}
}
}
throw lastException;
}
/**
* 限流切面
*/
@Around("@annotation(rateLimited)")
public Object handleRateLimit(ProceedingJoinPoint joinPoint,
RateLimited rateLimited) throws Throwable {
String key = rateLimited.key();
if (key.isEmpty()) {
key = joinPoint.getSignature().toShortString();
}
RateLimiter rateLimiter = RateLimiter.create(rateLimited.permitsPerSecond());
if (rateLimiter.tryAcquire(rateLimited.timeout(), TimeUnit.MILLISECONDS)) {
try {
return joinPoint.proceed();
} finally {
// 记录限流指标
metricRegistry.counter("rate.limiter.success", "key", key).increment();
}
} else {
// 限流触发
log.warn("触发限流: {} - 每秒允许{}个请求", key, rateLimited.permitsPerSecond());
metricRegistry.counter("rate.limiter.rejected", "key", key).increment();
if (rateLimited.fallbackEnabled()) {
return executeFallback(joinPoint, rateLimited);
} else {
throw new RateLimitExceededException("请求频率过高,请稍后重试");
}
}
}
private Object executeFallback(ProceedingJoinPoint joinPoint, CircuitBreaker circuitBreaker) {
String fallbackMethod = circuitBreaker.fallbackMethod();
if (StringUtils.hasText(fallbackMethod)) {
return fallbackMethodResolver.resolve(joinPoint, fallbackMethod);
}
return getDefaultFallbackResult(joinPoint);
}
private Object executeFallback(ProceedingJoinPoint joinPoint, RateLimited rateLimited) {
String fallbackMethod = rateLimited.fallbackMethod();
if (StringUtils.hasText(fallbackMethod)) {
return fallbackMethodResolver.resolve(joinPoint, fallbackMethod);
}
return getDefaultFallbackResult(joinPoint);
}
private Object getDefaultFallbackResult(ProceedingJoinPoint joinPoint) {
Class<?> returnType = ((MethodSignature) joinPoint.getSignature()).getReturnType();
if (returnType == void.class) {
return null;
} else if (returnType == String.class) {
return "服务暂时不可用,请稍后重试";
} else if (Collection.class.isAssignableFrom(returnType)) {
return Collections.emptyList();
} else if (returnType == boolean.class) {
return false;
} else {
return null;
}
}
private boolean shouldRetry(Exception e, Class<? extends Exception>[] retryFor) {
for (Class<? extends Exception> exceptionClass : retryFor) {
if (exceptionClass.isAssignableFrom(e.getClass())) {
return true;
}
}
return false;
}
}
/**
* 容错相关注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CircuitBreaker {
String name();
boolean fallbackEnabled() default true;
String fallbackMethod() default "";
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retryable {
int maxAttempts() default 3;
long delay() default 1000;
boolean exponentialBackoff() default false;
Class<? extends Exception>[] retryFor() default {Exception.class};
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimited {
String key() default "";
double permitsPerSecond() default 10.0;
long timeout() default 100;
boolean fallbackEnabled() default true;
String fallbackMethod() default "";
}
/**
* 自定义异常
*/
public class RateLimitExceededException extends RuntimeException {
public RateLimitExceededException(String message) {
super(message);
}
}/**
* AOP性能优化配置
* 针对生产环境的性能调优
*/
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@Slf4j
public class AOPPerformanceConfiguration {
/**
* 配置切面执行器
* 使用异步执行器处理非关键切面逻辑
*/
@Bean("aspectExecutor")
public Executor aspectExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(8);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("aspect-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
/**
* 切面性能监控器
*/
@Bean
public AspectPerformanceMonitor aspectPerformanceMonitor() {
return new AspectPerformanceMonitor();
}
/**
* 切面缓存配置
*/
@Bean
public CacheManager aspectCacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(Duration.ofMinutes(30))
.recordStats());
return cacheManager;
}
}
/**
* 切面性能监控器
*/
@Component
@Slf4j
public class AspectPerformanceMonitor {
private final MeterRegistry meterRegistry;
private final Map<String, Timer> aspectTimers = new ConcurrentHashMap<>();
private final Map<String, Counter> aspectCounters = new ConcurrentHashMap<>();
public AspectPerformanceMonitor(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
/**
* 记录切面执行时间
*/
public void recordAspectExecution(String aspectName, String methodName, long duration) {
String timerName = aspectName + "." + methodName;
Timer timer = aspectTimers.computeIfAbsent(timerName,
name -> Timer.builder("aspect.execution.time")
.tag("aspect", aspectName)
.tag("method", methodName)
.register(meterRegistry));
timer.record(duration, TimeUnit.MILLISECONDS);
}
/**
* 记录切面执行次数
*/
public void recordAspectCount(String aspectName, String methodName, boolean success) {
String counterName = aspectName + "." + methodName + "." + (success ? "success" : "failure");
Counter counter = aspectCounters.computeIfAbsent(counterName,
name -> Counter.builder("aspect.execution.count")
.tag("aspect", aspectName)
.tag("method", methodName)
.tag("result", success ? "success" : "failure")
.register(meterRegistry));
counter.increment();
}
/**
* 获取切面性能统计
*/
public AspectPerformanceStats getPerformanceStats(String aspectName) {
return new AspectPerformanceStats(aspectName, aspectTimers, aspectCounters);
}
/**
* 性能统计数据类
*/
public static class AspectPerformanceStats {
private final String aspectName;
private final Map<String, Timer> timers;
private final Map<String, Counter> counters;
public AspectPerformanceStats(String aspectName,
Map<String, Timer> timers,
Map<String, Counter> counters) {
this.aspectName = aspectName;
this.timers = new HashMap<>(timers);
this.counters = new HashMap<>(counters);
}
public double getAverageExecutionTime() {
return timers.values().stream()
.filter(timer -> timer.getId().getTag("aspect").equals(aspectName))
.mapToDouble(timer -> timer.mean(TimeUnit.MILLISECONDS))
.average()
.orElse(0.0);
}
public long getTotalExecutionCount() {
return counters.values().stream()
.filter(counter -> counter.getId().getTag("aspect").equals(aspectName))
.mapToLong(Counter::count)
.sum();
}
public double getSuccessRate() {
long successCount = counters.entrySet().stream()
.filter(entry -> entry.getKey().contains(aspectName) && entry.getKey().endsWith("success"))
.mapToLong(entry -> (long) entry.getValue().count())
.sum();
long totalCount = getTotalExecutionCount();
return totalCount > 0 ? (double) successCount / totalCount : 0.0;
}
}
}
/**
* 高性能日志切面
* 使用异步处理和批量写入优化性能
*/
@Aspect
@Component
@Slf4j
public class HighPerformanceLoggingAspect {
private final Executor aspectExecutor;
private final AspectPerformanceMonitor performanceMonitor;
private final BlockingQueue<LogEntry> logQueue = new LinkedBlockingQueue<>(10000);
private final ScheduledExecutorService batchProcessor = Executors.newSingleThreadScheduledExecutor();
public HighPerformanceLoggingAspect(@Qualifier("aspectExecutor") Executor aspectExecutor,
AspectPerformanceMonitor performanceMonitor) {
this.aspectExecutor = aspectExecutor;
this.performanceMonitor = performanceMonitor;
// 启动批量处理器
startBatchProcessor();
}
@Around("@annotation(performanceLogging)")
public Object logPerformance(ProceedingJoinPoint joinPoint,
PerformanceLogging performanceLogging) throws Throwable {
String methodName = joinPoint.getSignature().getName();
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - startTime;
// 异步记录日志
if (duration > performanceLogging.threshold()) {
CompletableFuture.runAsync(() -> {
LogEntry entry = new LogEntry(methodName, duration, true, null);
offerLogEntry(entry);
}, aspectExecutor);
}
// 记录性能指标
performanceMonitor.recordAspectExecution("PerformanceLogging", methodName, duration);
performanceMonitor.recordAspectCount("PerformanceLogging", methodName, true);
return result;
} catch (Exception e) {
long duration = System.currentTimeMillis() - startTime;
// 异步记录异常日志
CompletableFuture.runAsync(() -> {
LogEntry entry = new LogEntry(methodName, duration, false, e.getMessage());
offerLogEntry(entry);
}, aspectExecutor);
performanceMonitor.recordAspectCount("PerformanceLogging", methodName, false);
throw e;
}
}
private void offerLogEntry(LogEntry entry) {
if (!logQueue.offer(entry)) {
log.warn("日志队列已满,丢弃日志条目: {}", entry.getMethodName());
}
}
private void startBatchProcessor() {
batchProcessor.scheduleAtFixedRate(() -> {
List<LogEntry> batch = new ArrayList<>();
logQueue.drainTo(batch, 100); // 批量处理100条日志
if (!batch.isEmpty()) {
processBatch(batch);
}
}, 1, 1, TimeUnit.SECONDS);
}
private void processBatch(List<LogEntry> batch) {
try {
// 批量写入日志
StringBuilder logBuilder = new StringBuilder();
for (LogEntry entry : batch) {
logBuilder.append(String.format("[%s] %s - 耗时: %dms - 成功: %s%s%n",
new Date(), entry.getMethodName(), entry.getDuration(),
entry.isSuccess(), entry.getErrorMessage() != null ? " - 错误: " + entry.getErrorMessage() : ""));
}
log.info("批量处理日志 - 条数: {}\n{}", batch.size(), logBuilder.toString());
} catch (Exception e) {
log.error("批量处理日志失败", e);
}
}
@PreDestroy
public void shutdown() {
batchProcessor.shutdown();
try {
if (!batchProcessor.awaitTermination(5, TimeUnit.SECONDS)) {
batchProcessor.shutdownNow();
}
} catch (InterruptedException e) {
batchProcessor.shutdownNow();
Thread.currentThread().interrupt();
}
}
/**
* 日志条目
*/
private static class LogEntry {
private final String methodName;
private final long duration;
private final boolean success;
private final String errorMessage;
public LogEntry(String methodName, long duration, boolean success, String errorMessage) {
this.methodName = methodName;
this.duration = duration;
this.success = success;
this.errorMessage = errorMessage;
}
// Getters
public String getMethodName() { return methodName; }
public long getDuration() { return duration; }
public boolean isSuccess() { return success; }
public String getErrorMessage() { return errorMessage; }
}
}
/**
* 性能日志注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PerformanceLogging {
long threshold() default 1000; // 毫秒
boolean async() default true;
}/**
* AOP监控切面
* 提供全面的监控和告警功能
*/
@Aspect
@Component
@Slf4j
public class MonitoringAspect {
private final MeterRegistry meterRegistry;
private final AlertManager alertManager;
private final HealthIndicatorRegistry healthIndicatorRegistry;
public MonitoringAspect(MeterRegistry meterRegistry,
AlertManager alertManager,
HealthIndicatorRegistry healthIndicatorRegistry) {
this.meterRegistry = meterRegistry;
this.alertManager = alertManager;
this.healthIndicatorRegistry = healthIndicatorRegistry;
}
/**
* 系统健康检查切面
*/
@Around("@annotation(healthCheck)")
public Object monitorHealth(ProceedingJoinPoint joinPoint,
HealthCheck healthCheck) throws Throwable {
String serviceName = healthCheck.service();
Timer.Sample sample = Timer.start(meterRegistry);
try {
Object result = joinPoint.proceed();
// 记录成功指标
sample.stop(Timer.builder("health.check")
.tag("service", serviceName)
.tag("status", "success")
.register(meterRegistry));
// 更新健康状态
updateHealthStatus(serviceName, true, null);
return result;
} catch (Exception e) {
// 记录失败指标
sample.stop(Timer.builder("health.check")
.tag("service", serviceName)
.tag("status", "failure")
.register(meterRegistry));
// 更新健康状态
updateHealthStatus(serviceName, false, e.getMessage());
// 触发告警
if (healthCheck.alertOnFailure()) {
alertManager.sendAlert(AlertLevel.ERROR,
String.format("服务健康检查失败: %s - %s", serviceName, e.getMessage()));
}
throw e;
}
}
/**
* 业务指标监控
*/
@Around("@annotation(businessMetric)")
public Object monitorBusinessMetric(ProceedingJoinPoint joinPoint,
BusinessMetric businessMetric) throws Throwable {
String metricName = businessMetric.name();
String[] tags = businessMetric.tags();
// 增加调用计数
Counter.builder("business.metric.calls")
.tags(tags)
.tag("metric", metricName)
.register(meterRegistry)
.increment();
Timer.Sample sample = Timer.start(meterRegistry);
try {
Object result = joinPoint.proceed();
// 记录执行时间
sample.stop(Timer.builder("business.metric.duration")
.tags(tags)
.tag("metric", metricName)
.register(meterRegistry));
// 记录业务指标值
if (result instanceof Number) {
Gauge.builder("business.metric.value")
.tags(tags)
.tag("metric", metricName)
.register(meterRegistry, result, value -> ((Number) value).doubleValue());
}
return result;
} catch (Exception e) {
// 记录错误指标
Counter.builder("business.metric.errors")
.tags(tags)
.tag("metric", metricName)
.tag("error", e.getClass().getSimpleName())
.register(meterRegistry)
.increment();
throw e;
}
}
/**
* SLA监控切面
*/
@Around("@annotation(slaMonitoring)")
public Object monitorSLA(ProceedingJoinPoint joinPoint,
SLAMonitoring slaMonitoring) throws Throwable {
String operation = slaMonitoring.operation();
long slaThreshold = slaMonitoring.thresholdMs();
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - startTime;
// 记录SLA指标
Timer.builder("sla.response.time")
.tag("operation", operation)
.register(meterRegistry)
.record(duration, TimeUnit.MILLISECONDS);
// 检查SLA违规
if (duration > slaThreshold) {
Counter.builder("sla.violations")
.tag("operation", operation)
.register(meterRegistry)
.increment();
// 发送SLA告警
alertManager.sendAlert(AlertLevel.WARNING,
String.format("SLA违规: %s - 响应时间: %dms (阈值: %dms)",
operation, duration, slaThreshold));
}
return result;
} catch (Exception e) {
// 记录错误率
Counter.builder("sla.errors")
.tag("operation", operation)
.register(meterRegistry)
.increment();
throw e;
}
}
private void updateHealthStatus(String serviceName, boolean healthy, String errorMessage) {
HealthIndicator indicator = healthy ?
() -> Health.up().build() :
() -> Health.down().withDetail("error", errorMessage).build();
healthIndicatorRegistry.register(serviceName, indicator);
}
}
/**
* 告警管理器
*/
@Component
@Slf4j
public class AlertManager {
private final List<AlertChannel> alertChannels;
private final AlertRuleEngine ruleEngine;
public AlertManager(List<AlertChannel> alertChannels, AlertRuleEngine ruleEngine) {
this.alertChannels = alertChannels;
this.ruleEngine = ruleEngine;
}
public void sendAlert(AlertLevel level, String message) {
Alert alert = new Alert(level, message, System.currentTimeMillis());
// 应用告警规则
if (ruleEngine.shouldSendAlert(alert)) {
alertChannels.forEach(channel -> {
try {
channel.sendAlert(alert);
} catch (Exception e) {
log.error("发送告警失败: {}", channel.getClass().getSimpleName(), e);
}
});
}
}
}
/**
* 监控相关注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HealthCheck {
String service();
boolean alertOnFailure() default true;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BusinessMetric {
String name();
String[] tags() default {};
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SLAMonitoring {
String operation();
long thresholdMs() default 1000;
}
/**
* 告警级别枚举
*/
public enum AlertLevel {
INFO, WARNING, ERROR, CRITICAL
}
/**
* 告警实体
*/
public class Alert {
private final AlertLevel level;
private final String message;
private final long timestamp;
public Alert(AlertLevel level, String message, long timestamp) {
this.level = level;
this.message = message;
this.timestamp = timestamp;
}
// Getters
public AlertLevel getLevel() { return level; }
public String getMessage() { return message; }
public long getTimestamp() { return timestamp; }
}通过本文的深入学习,我们全面掌握了SpringBoot AOP切面编程的核心技术和实战应用。让我们回顾一下主要的知识点:
AOP基础理论:
SpringBoot AOP特性:
高级切点表达式技巧:
// 组合切点表达式
@Pointcut("execution(* com.example.service..*Service.*(..)) && @annotation(Transactional)")
public void transactionalServiceMethods() {}
// 参数类型匹配
@Pointcut("execution(* *..*Service.save*(..)) && args(entity,..)")
public void saveOperations(Object entity) {}
// Bean名称匹配
@Pointcut("bean(*Service) && !bean(internalService)")
public void publicServices() {}动态切面编程模式:
企业级架构集成:
Spring官方资源:
技术博客与社区:
推荐开源项目:
学习路径建议:
配套技术学习:
编译时织入的兴起: 随着GraalVM和Spring Native的发展,编译时AOP织入将成为重要趋势,提供更好的性能和更小的内存占用。
响应式编程集成: AOP与WebFlux、Project Reactor等响应式框架的深度集成,支持异步非阻塞的切面编程。
云原生AOP:
AI/ML集成:
边缘计算:
问题1:在高并发场景下,如何平衡AOP功能丰富性与性能开销?
讨论要点:
问题2:动态切面与静态切面的选择标准是什么?
讨论要点:
问题3:在微服务架构中,切面逻辑应该如何分层和解耦?
讨论要点:
问题4:如何设计一个可扩展的企业级AOP框架?
讨论要点:
争议1:是否应该在Controller层使用AOP?
不同观点:
争议2:AOP与装饰器模式的选择?
对比分析:
技术社区参与:
持续学习计划:
项目实战:
团队协作:
SpringBoot AOP切面编程作为现代Java企业级开发的重要技术,为我们提供了优雅解决横切关注点的方案。通过本文的学习,相信大家已经掌握了从基础概念到高级应用的完整知识体系。
AOP不仅仅是一种编程技术,更是一种设计思想。它教会我们如何在复杂的业务系统中保持代码的整洁性和可维护性,如何通过合理的关注点分离来构建更加健壮的应用架构。
技术的学习永无止境,希望大家能够:
如果这篇文章对您有帮助,请不要忘记:
让我们一起在SpringBoot AOP的技术道路上不断前行,构建更加优秀的企业级应用!