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 -> Logging2. 条件拦截
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();
}
}注意事项
- 性能影响:每个拦截器都会增加方法调用开销,避免过多拦截器
- 异常传播:确保异常正确传播,不要吞掉异常
- 线程安全:拦截器可能被多线程调用,注意线程安全
- 资源清理:在 finally 块中清理资源
- 避免副作用:拦截器应该是无状态的或线程安全的