Skip to content

AOP 支持

LCGYL Framework 提供了强大的 AOP(面向切面编程)支持,基于 JDK 动态代理和拦截器链实现,无需依赖第三方 AOP 框架。

核心概念

什么是 AOP?

AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,用于将横切关注点(Cross-cutting Concerns)从业务逻辑中分离出来。

横切关注点示例

  • 日志记录
  • 性能监控
  • 事务管理
  • 权限检查
  • 异常处理
  • 缓存管理

核心组件

java
// 拦截器接口
public interface Interceptor {
    Object intercept(Invocation invocation) throws Throwable;
}

// 调用上下文
public record Invocation(
    Object target,
    Method method,
    Object[] args,
    InterceptorChain chain
) {
    public Object proceed() throws Throwable {
        return chain.proceed(this);
    }
}

// 代理工厂
public class ProxyFactory {
    public static <T> T createProxy(T target, List<Interceptor> interceptors);
}

基础使用

1. 创建拦截器

java
import com.lcgyl.core.aop.Interceptor;
import com.lcgyl.core.aop.Invocation;

// 日志拦截器
public class LoggingInterceptor implements Interceptor {
    
    private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Method method = invocation.method();
        Object[] args = invocation.args();
        
        logger.info("调用方法: {}.{}", 
            method.getDeclaringClass().getSimpleName(),
            method.getName()
        );
        logger.debug("参数: {}", Arrays.toString(args));
        
        long startTime = System.currentTimeMillis();
        
        try {
            // 继续执行
            Object result = invocation.proceed();
            
            long duration = System.currentTimeMillis() - startTime;
            logger.info("方法执行成功,耗时: {}ms", duration);
            
            return result;
        } catch (Throwable e) {
            logger.error("方法执行失败: {}", e.getMessage(), e);
            throw e;
        }
    }
}

2. 创建代理

java
import com.lcgyl.core.aop.ProxyFactory;

public class ServiceExample {
    
    public static void main(String[] args) {
        // 原始服务
        UserService userService = new UserServiceImpl();
        
        // 创建拦截器
        List<Interceptor> interceptors = List.of(
            new LoggingInterceptor(),
            new PerformanceInterceptor(),
            new TransactionInterceptor()
        );
        
        // 创建代理
        UserService proxy = ProxyFactory.createProxy(userService, interceptors);
        
        // 使用代理
        User user = proxy.getUserById(1L);
    }
}

内置拦截器

1. 性能监控拦截器

java
public class PerformanceInterceptor implements Interceptor {
    
    private static final Logger logger = LoggerFactory.getLogger(PerformanceInterceptor.class);
    private final long threshold; // 阈值(毫秒)
    
    public PerformanceInterceptor(long threshold) {
        this.threshold = threshold;
    }
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long startTime = System.nanoTime();
        
        try {
            return invocation.proceed();
        } finally {
            long duration = (System.nanoTime() - startTime) / 1_000_000;
            
            if (duration > threshold) {
                logger.warn("慢方法检测: {}.{} 耗时 {}ms(阈值: {}ms)",
                    invocation.method().getDeclaringClass().getSimpleName(),
                    invocation.method().getName(),
                    duration,
                    threshold
                );
            }
        }
    }
}

// 使用
List<Interceptor> interceptors = List.of(
    new PerformanceInterceptor(100) // 超过 100ms 警告
);

2. 事务拦截器

java
public class TransactionInterceptor implements Interceptor {
    
    private final TransactionManager transactionManager;
    
    public TransactionInterceptor(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Method method = invocation.method();
        
        // 检查是否需要事务
        if (!method.isAnnotationPresent(Transactional.class)) {
            return invocation.proceed();
        }
        
        // 开启事务
        transactionManager.begin();
        
        try {
            Object result = invocation.proceed();
            
            // 提交事务
            transactionManager.commit();
            
            return result;
        } catch (Throwable e) {
            // 回滚事务
            transactionManager.rollback();
            throw e;
        }
    }
}

3. 缓存拦截器

java
public class CacheInterceptor implements Interceptor {
    
    private final Map<String, Object> cache = new ConcurrentHashMap<>();
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Method method = invocation.method();
        
        // 检查是否需要缓存
        if (!method.isAnnotationPresent(Cacheable.class)) {
            return invocation.proceed();
        }
        
        // 生成缓存键
        String key = generateKey(invocation);
        
        // 检查缓存
        Object cached = cache.get(key);
        if (cached != null) {
            return cached;
        }
        
        // 执行方法
        Object result = invocation.proceed();
        
        // 缓存结果
        cache.put(key, result);
        
        return result;
    }
    
    private String generateKey(Invocation invocation) {
        return invocation.method().getName() + 
               Arrays.hashCode(invocation.args());
    }
}

4. 重试拦截器

java
public class RetryInterceptor implements Interceptor {
    
    private static final Logger logger = LoggerFactory.getLogger(RetryInterceptor.class);
    private final int maxRetries;
    private final long retryDelay;
    
    public RetryInterceptor(int maxRetries, long retryDelay) {
        this.maxRetries = maxRetries;
        this.retryDelay = retryDelay;
    }
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        int attempts = 0;
        Throwable lastException = null;
        
        while (attempts < maxRetries) {
            try {
                return invocation.proceed();
            } catch (Throwable e) {
                lastException = e;
                attempts++;
                
                if (attempts < maxRetries) {
                    logger.warn("方法执行失败,第 {} 次重试", attempts);
                    Thread.sleep(retryDelay);
                }
            }
        }
        
        logger.error("方法执行失败,已达最大重试次数: {}", maxRetries);
        throw lastException;
    }
}

高级特性

1. 拦截器链

拦截器按照添加顺序执行,形成拦截器链:

java
List<Interceptor> interceptors = List.of(
    new LoggingInterceptor(),      // 1. 记录日志
    new PerformanceInterceptor(),  // 2. 性能监控
    new CacheInterceptor(),        // 3. 缓存检查
    new TransactionInterceptor()   // 4. 事务管理
);

// 执行顺序:
// Logging -> Performance -> Cache -> Transaction -> 目标方法
// Transaction -> Cache -> Performance -> Logging

2. 条件拦截

java
public class ConditionalInterceptor implements Interceptor {
    
    private final Predicate<Invocation> condition;
    private final Interceptor delegate;
    
    public ConditionalInterceptor(Predicate<Invocation> condition, 
                                   Interceptor delegate) {
        this.condition = condition;
        this.delegate = delegate;
    }
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        if (condition.test(invocation)) {
            return delegate.intercept(invocation);
        }
        return invocation.proceed();
    }
}

// 使用
Interceptor conditionalLogger = new ConditionalInterceptor(
    inv -> inv.method().getName().startsWith("save"),
    new LoggingInterceptor()
);

3. 方法匹配器

java
public class MethodMatcherInterceptor implements Interceptor {
    
    private final Pattern methodPattern;
    private final Interceptor delegate;
    
    public MethodMatcherInterceptor(String methodPattern, Interceptor delegate) {
        this.methodPattern = Pattern.compile(methodPattern);
        this.delegate = delegate;
    }
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        String methodName = invocation.method().getName();
        
        if (methodPattern.matcher(methodName).matches()) {
            return delegate.intercept(invocation);
        }
        
        return invocation.proceed();
    }
}

// 使用
Interceptor saveLogger = new MethodMatcherInterceptor(
    "save.*|update.*|delete.*",
    new LoggingInterceptor()
);

实战示例

完整的服务代理

java
public class UserServiceExample {
    
    public static void main(String[] args) {
        // 1. 创建原始服务
        UserService userService = new UserServiceImpl();
        
        // 2. 配置拦截器
        List<Interceptor> interceptors = List.of(
            // 日志记录
            new LoggingInterceptor(),
            
            // 性能监控(超过 100ms 警告)
            new PerformanceInterceptor(100),
            
            // 缓存(仅查询方法)
            new ConditionalInterceptor(
                inv -> inv.method().getName().startsWith("get"),
                new CacheInterceptor()
            ),
            
            // 事务管理(仅修改方法)
            new ConditionalInterceptor(
                inv -> inv.method().getName().matches("save|update|delete"),
                new TransactionInterceptor(transactionManager)
            ),
            
            // 重试(网络调用)
            new MethodMatcherInterceptor(
                ".*Remote.*",
                new RetryInterceptor(3, 1000)
            )
        );
        
        // 3. 创建代理
        UserService proxy = ProxyFactory.createProxy(userService, interceptors);
        
        // 4. 使用代理
        User user = proxy.getUserById(1L);        // 触发:日志、性能、缓存
        proxy.saveUser(user);                      // 触发:日志、性能、事务
        proxy.callRemoteService();                 // 触发:日志、性能、重试
    }
}

自定义注解驱动

java
// 1. 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Monitored {
    long threshold() default 100;
}

// 2. 创建注解驱动的拦截器
public class MonitoredInterceptor implements Interceptor {
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Method method = invocation.method();
        Monitored monitored = method.getAnnotation(Monitored.class);
        
        if (monitored == null) {
            return invocation.proceed();
        }
        
        long startTime = System.nanoTime();
        
        try {
            return invocation.proceed();
        } finally {
            long duration = (System.nanoTime() - startTime) / 1_000_000;
            
            if (duration > monitored.threshold()) {
                System.out.printf("慢方法: %s 耗时 %dms%n", 
                    method.getName(), duration);
            }
        }
    }
}

// 3. 使用注解
public class UserServiceImpl implements UserService {
    
    @Monitored(threshold = 50)
    public User getUserById(Long id) {
        // 查询用户
        return userRepository.findById(id);
    }
    
    @Monitored(threshold = 200)
    public void saveUser(User user) {
        // 保存用户
        userRepository.save(user);
    }
}

最佳实践

1. 拦截器顺序

合理安排拦截器顺序,通常遵循以下原则:

java
List<Interceptor> interceptors = List.of(
    new LoggingInterceptor(),      // 1. 最外层:记录所有调用
    new PerformanceInterceptor(),  // 2. 性能监控
    new SecurityInterceptor(),     // 3. 权限检查
    new CacheInterceptor(),        // 4. 缓存(避免不必要的执行)
    new TransactionInterceptor(),  // 5. 事务管理
    new RetryInterceptor()         // 6. 最内层:重试逻辑
);

2. 异常处理

java
public class ExceptionHandlingInterceptor implements Interceptor {
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        try {
            return invocation.proceed();
        } catch (BusinessException e) {
            // 业务异常:记录并重新抛出
            logger.warn("业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            // 系统异常:包装后抛出
            logger.error("系统异常", e);
            throw new SystemException("系统错误", e);
        }
    }
}

3. 性能优化

java
// 使用 ThreadLocal 避免重复创建对象
public class OptimizedInterceptor implements Interceptor {
    
    private static final ThreadLocal<Context> contextHolder = 
        ThreadLocal.withInitial(Context::new);
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Context context = contextHolder.get();
        
        try {
            context.startTime = System.nanoTime();
            return invocation.proceed();
        } finally {
            context.clear();
        }
    }
    
    private static class Context {
        long startTime;
        
        void clear() {
            startTime = 0;
        }
    }
}

4. 避免循环依赖

java
// ❌ 错误:拦截器之间相互调用
public class BadInterceptor implements Interceptor {
    private final AnotherInterceptor another;
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        another.doSomething(); // 可能导致循环
        return invocation.proceed();
    }
}

// ✅ 正确:拦截器独立工作
public class GoodInterceptor implements Interceptor {
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 独立的逻辑
        doMyWork();
        return invocation.proceed();
    }
}

注意事项

  1. 性能影响:每个拦截器都会增加方法调用开销,避免过多拦截器
  2. 异常传播:确保异常正确传播,不要吞掉异常
  3. 线程安全:拦截器可能被多线程调用,注意线程安全
  4. 资源清理:在 finally 块中清理资源
  5. 避免副作用:拦截器应该是无状态的或线程安全的

下一步

Released under the Apache License 2.0