用于父子关系类的Spring AOP

问题描述 投票:0回答:1

我正在处理现有代码,并且正在为请求编写一些审计。 我尝试了多种方法,但我的切入点表达式没有被执行。

我创建了一个单独的类,它具有类似的注释,没有任何父级和子级层次结构,并且我能够调用这些切入点表达式。

我不确定当存在父子关系时应该使用什么切入点表达式。

public interface Parent {
      @GetMapping(value = "/test")
      ResponseEntity<?> createJsonSchemaMetadata();

}

我的孩子班

@RestController
@Validated
@RequestMapping("/api")
public class Child implements Parent {

    @Override
    public ResponseEntity<?> createJsonSchemaMetadata() {
        return ResponseEntity.status(HttpStatus.OK).body("Successful");
    }
}

我的切入点表达式:

@Aspect
public class PointcutDefinition {

    // targeting GET,POST,PUT,DELETE methods
    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping) "
            + "|| @annotation(org.springframework.web.bind.annotation.PutMapping)"
            + "|| @annotation(org.springframework.web.bind.annotation.DeleteMapping)")
    public void httpMethodsWithAnnotation() {
    }

    // targeting methods which are defined using RequestMapping.
    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void requestMappingMethodsWithHttpMethods() {
    }

}

我的建议:

@Aspect
@Component
public class AuditingAspect {

    private static final Logger log = LoggerFactory.getLogger(AuditingAspect.class);

    
    @Around(" PointcutDefinition.httpMethodsWithAnnotation() || PointcutDefinition.requestMappingMethodsWithHttpMethods()")
    public Object auditAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        if (log.isTraceEnabled()) {
            log.trace("Entering auditAdvice method in " + this.getClass());
        }
        System.out.println("Auditing triggered.");
        Object proceed = joinPoint.proceed();
        return proceed;
    }
}

我发现这些切入点表达式没有调用我的建议。有人可以帮忙吗。

java spring spring-boot aop spring-aop
1个回答
0
投票

M。 Deinum 关于注释继承的说法是正确的。除了一个非常特殊的例外,它在 Java 中基本上不存在。详情请参阅我的回答。除了使用高级本机 AspectJ 之外,如此处所述,最简单的解决方法不是注释接口方法,而是注释实现类的方法:

@Override
@GetMapping(value = "/test")
public ResponseEntity<?> createJsonSchemaMetadata() {
  return ResponseEntity.status(HttpStatus.OK).body("Successful");
}

您还需要确保没有 JDK 代理用于重写接口的类,而是使用 CGLIB 代理。在 Spring Boot 中,这是默认设置。在普通的 vanilla Spring 中,您可以使用

@EnableAspectJAutoProxy(proxyTargetClass = true)

关于你的第二个切入点,它完全是错误的:

@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")

这个目标是带注释的方法,但是你想拦截带注释的类中的方法,这是不同的,需要这样表达:

@Pointcut("@within(org.springframework.web.bind.annotation.RequestMapping)")
© www.soinside.com 2019 - 2024. All rights reserved.