springboot@Aspect日志

springboot@Aspect日志,spring,spring-boot,logging,aspect,Spring,Spring Boot,Logging,Aspect,我尝试使用@Aspect记录所有请求和响应。如果我的端点有@RequestBody,那么我的代码正在工作,但是我的get端点没有@RequestBody,并且我看不到日志。这能解释这种情况吗 我的班级是这样的 @Aspect @Component @Slf4j @RequiredArgsConstructor(onConstructor = @__({@Autowired, @NotNull})) public class AspectLogging { private final O

我尝试使用@Aspect记录所有请求和响应。如果我的端点有@RequestBody,那么我的代码正在工作,但是我的get端点没有@RequestBody,并且我看不到日志。这能解释这种情况吗

我的班级是这样的

@Aspect
@Component
@Slf4j
@RequiredArgsConstructor(onConstructor = @__({@Autowired, @NotNull}))
public class AspectLogging {

    private final ObjectMapper objectMapper;

    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping)")
    public void annotationPointCutDefinition() {

    }

    @Pointcut("execution(* *(com.dux.secondwallet.api.v3.pay.merchant.*))")
    public void atExecution() {
    }

    @Before("annotationPointCutDefinition() && atExecution()")
    public void endpointBefore(JoinPoint p) {
        Object[] signatureArgs = p.getArgs();
        if (Objects.nonNull(signatureArgs) && signatureArgs.length > 0) {
            log.info("Request object: " + signatureArgs[0]);
        }
    }

    @AfterReturning(pointcut = "annotationPointCutDefinition() && atExecution()", returning = "returnValue")
    public void endpointAfterReturning(Object returnValue) {
        try {
            log.info("Response object:" + objectMapper.writeValueAsString(returnValue));
        } catch (JsonProcessingException e) {
            log.error(e.getMessage(), e);
        }
    }


    @AfterThrowing(pointcut = "annotationPointCutDefinition() && atExecution()", throwing = "e")
    public void endpointAfterThrowing(JoinPoint p, Exception e) throws Exception {
        e.printStackTrace();
        log.error(p.getTarget().getClass().getSimpleName() + " " + p.getSignature().getName() + " " + e.getMessage());
    }
}
示例控制器;getRequest方法未记录,postRequest记录

 @Slf4j
@RestController
@RequestMapping("/v3/")
public class MyController {

    @GetMapping("/balances")//not before and after logging
    public List<java.lang.String> getRequest() {
        return Collections.singletonList("TEST");
    }

    @PostMapping("/limits")//its logging
    public TransactionLimitResponse postRequest(@Valid @RequestBody TransactionLimitRequest transactionLimitRequest) {
        return TransactionLimitResponse.builder()
                .currency("EUR")
                .type("TYPE")
                .min(100)
                .max(1000)
                .build();
    }
}
@Slf4j
@RestController
@请求映射(“/v3/”)
公共类MyController{
@GetMapping(“/balances”)//不在日志记录之前和之后
公共列表getRequest(){
返回集合。单音列表(“测试”);
}
@PostMapping(“/limits”)//它的日志记录
公共TransactionLimitResponse postRequest(@Valid@RequestBody TransactionLimitRequest TransactionLimitRequest){
返回TransactionLimitResponse.builder()
.货币(“欧元”)
.类型(“类型”)
.min(100)
.最大值(1000)
.build();
}
}

您的切入点定义不清楚。使用
@Pointcut(“execution(*com.dux.secondwallet.api.v3.pay.merchant.*.*(…)”)
切入点将匹配定义包下类中的所有方法

提示


此外,对于方面配置类,您应该使用
@Configuration
,而不是
@Component
。此外,通过在实例字段上使用
@NonNull
,您可以跳过
@RequiredArgsConstructor
配置。

首先,我想问您想要记录什么

方面代码的目的是记录方法参数,而@GetMapping方法上没有任何参数

因此@GetMapping也成功触发了aspect方法。但只需检查条件是否满足并通过即可。你看不到日志是很正常的

应用以下更改,它将起作用:

@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
//@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping))")
public void getMapping() {

}

@Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
//@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping))")
public void postMapping() {

}


 @Pointcut("execution(* *(..)) && within(com.dux.secondwallet.api.v3.pay.merchant.*))")
    public void atExecution() {
    }

@Before("(getMapping() || postMapping()) && atExecution()")
public void endpointBefore(JoinPoint p) {
    log.info("ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss");
    Object[] signatureArgs = p.getArgs();
    if (Objects.nonNull(signatureArgs) && signatureArgs.length > 0) {
        log.info("Request object: " + signatureArgs[0]);
    }else{
        log.info("log for get");
    }
}
执行(**(..)
:这是您的方法签名


在(com.dux.secondwallet.api.v3.pay.merchant.*)
这是包限制。

您的方面在方法签名中查找参数,如果没有参数,则跳过日志记录。@Taylor怎么能通过它?我想在请求之前和请求之后看到标题或其他内容。首先,我想在请求之前看到标题或其他内容。我以前说过。如果我的方面代码的目的是记录方法参数,那么您可以说我的方面代码是如何触发@GetMapping的吗?你说的是哪种情况?@Rhmn61我已经更新了我的答案。你现在可以运行它了。