编辑
2026-04-15
后端
00

Spring aop 面向切面编程

1、作用

不修改原有代码逻辑,通过切点的方式,提高代码可读性

2、术语

Aspect: 切面: 切面类,封装切面类执行逻辑

JoinPoint: 连接点: 被AOP连接的目标类的方法;可以插入切面的点

Advice: 通知: 在连接点具体动作,Before,Around

Pointcut: 切点: 执行到哪些目标方法上

3、通知分类

Before 前置通知 方法执行前;Around环绕通知,自定义前后行为;

4、通过Spring AOP实现日志审计

自定义注解实现切点

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) public @interface Auditable { String value() default ""; }

日志类

@Data
@AllArgsConstructor public class Syslog { private String methodName; private String message; private String args; private String result; private String status; private String exception; }

切面类

/**
* 切面类 * */ @Component @Aspect public class AuditAspect { private static final Logger logger = LoggerFactory.getLogger(AuditAspect.class); @Around("@annotation(auditable)") public Object audit(ProceedingJoinPoint joinPoint, Auditable auditable) throws Throwable { String methodName = joinPoint.getSignature().getName(); String message = auditable.value(); // 获取参数 Object[] args = joinPoint.getArgs(); String arrsString = args != null ? Arrays.stream(args).map(Object::toString).collect(Collectors.joining(",")) : null; Syslog syslog = new Syslog(methodName, message, arrsString, null, null, null); try { Object proceed = joinPoint.proceed(); syslog.setResult(proceed == null ? "null" : proceed.toString()); syslog.setStatus("成功"); return proceed; } catch (Throwable e) { syslog.setStatus("失败"); syslog.setException(e.getMessage()); throw e; } finally { logger.info("日志审计记录: {}", syslog); } } }

5、灵境给的使用示例

@Aspect
@Component public class LoggingAspect { // 定义切点:service 包下所有方法 @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethod() {} @Before("serviceMethod()") public void logBefore(JoinPoint joinPoint) { System.out.println("调用方法:" + joinPoint.getSignature().getName()); } @Around("serviceMethod()") public Object measureTime(ProceedingJoinPoint pjp) throws Throwable { long start = System.currentTimeMillis(); Object result = pjp.proceed(); long time = System.currentTimeMillis() - start; System.out.println(pjp.getSignature() + " 耗时 " + time + "ms"); return result; } }

本文作者:寒江孤影

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!