AOP业务

AOP业务

业务逻辑描述

日志记录

1

示例代码

AOP(Aspect Oriented Programming),面向切面编程,是一种将横向业务逻辑与纵向基础逻辑分离的编程模式。在实际项目中,AOP可以帮助我们避免代码重复、提高代码的可维护性和可扩展性,下面是AOP在项目中的常用场景和示例代码:

1、日志记录:

在方法执行前后记录方法的执行时间、请求参数和返回值等信息,以便于后续的系统运维和问题排查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Aspect
@Component
public class LogAspect {

@Before("execution(* com.example.service.*.*(..))")
public void before(JoinPoint joinPoint) {
// 方法执行前记录日志
...
}

@AfterReturning(returning = "result", pointcut = "execution(* com.example.service.*.*(..))")
public void after(JoinPoint joinPoint, Object result) {
// 方法执行后记录日志
...
}

@AfterThrowing(throwing = "ex", pointcut = "execution(* com.example.service.*.*(..))")
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
// 方法执行抛出异常时记录日志
...
}
}

2、权限控制

在方法执行前判断用户是否有访问该方法的权限,以及验证访问的参数是否合法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Aspect
@Component
public class AuthAspect {

@Before("execution(* com.example.controller.*.*(..))")
public void checkAuth(JoinPoint joinPoint) {
// 鉴权操作
...
}

@Before("execution(* com.example.controller.*.*(..)) && args(userId)")
public void checkUserId(String userId) {
// 验证访问的userId是否合法
...
}
}

3、统计方法执行次数和耗时

:在方法执行前后记录方法的执行时间、执行次数等信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Aspect
@Component
public class MetricsAspect {

private static final Logger logger = LoggerFactory.getLogger(MetricsAspect.class);

private final Map<String, AtomicInteger> counters = new ConcurrentHashMap<>();
private final Map<String, LongAdder> timers = new ConcurrentHashMap<>();

@Before("execution(* com.example.service.*.*(..))")
public void recordCount(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
counters.computeIfAbsent(methodName, key -> new AtomicInteger(0)).incrementAndGet();
}

@Around("execution(* com.example.service.*.*(..))")
public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName =Point.getSignature().getName();
long startTime = System.currentTimeMillis();
try {
return joinPoint.proceed();
} finally {
long timeTaken = System.currentTimeMillis() - startTime;
timers.computeIfAbsent(methodName, -> new LongAdder()).add(timeTaken);
logger.debug("Method {} invoked in {} ms", methodName, timeTaken);
}
}

@Scheduled(fixedRate = 60000)
public void logMetrics() {
// 定时输出统计信息
counters.forEach((methodName, value) -> logger.debug("Method {} invoked {} times", methodName, value.get()));
timers.forEach((methodName, value) -> logger.debug("Method {} took {} ms in total methodName, value.sum()));
}
}

以上代码示例展示了如何使用 AOP 统计方法执行次数和耗时,定时输出统计信息。使用 AOP 统计方法执行次数和耗时,可以帮助我们了解系统中各种方法的工作情况,从而优化系统性能。

4、缓存处理

:对于频繁访问的方法,可以将调用的结果缓存起来,减少方法执行的时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Aspect
@Component
public class CacheAspect {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Around("execution(* com.example.service.*.*))")
public Object cacheResult(ProceedingJoinPoint joinPoint) throws Throwable {
// 缓存处理
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
String key = generateKey(methodName, args);
ValueOperations<String, Object> valueOps = redisTemplate.opsForValue();
if (redisTemplate.hasKey(key)) {
return valueOps.get(key);
} else {
Object obj = joinPoint.proceed();
valueOps.set(key, obj);
return obj;
}
}

private String generateKey(String methodName, Object[] args) {
// 生成缓存键值
...
}
}

5、事务管理

:对于需要进行事务回滚的方法,可以使用AOP来实现事务的管理和控制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Aspect
@Component
public class TransactionAspect {

@Autowired
private PlatformTransactionManager transactionManager;

@Around("execution(* com.example.service.*.*))")
public Object transactional(ProceedingJoinPoint joinPoint) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
Object result = joinPoint.proceed();
transactionManager.commit(status);
return result;
} catch (Throwable e) {
transactionManager.rollback(status);
throw e;
}
}
}

综上所述,AOP在项目中有很多应用场景,可以通过AOP优雅地解决一些横切性问题,避免代码重复,提高代码的可维护性和可扩展性。


AOP业务
http://example.com/2023/06/01/业务/AOP业务/
作者
where
发布于
2023年6月1日
许可协议