首页 > 解决方案 > 在 Spring Boot 应用程序中,每次方法调用都会调用 Aspect 类中的方法两次

问题描述

@Aspect
public class ControllerLogger {

    @Autowired
    InfobloxLogsMapper infobloxLogsMapper;

    Logger log = LoggerFactory.getLogger(ControllerLogger.class);
    LogResquestAndResponse logsMapper = new LogResquestAndResponse();

    private final RequestInformationProvider infoProvider;

    public ControllerLogger() {
        infoProvider = new RequestInformationProvider();
    }

    // for unit testing only
    ControllerLogger(Logger log, RequestInformationProvider infoProvider) {
                this.infoProvider = infoProvider;
                this.log = log;
            }

    @Before("execution(* com.tr.dco.fp.ipam.controller..*.*(..))")
    public void logBefore(JoinPoint joinPoint){
        List<Object> paramList =Arrays.asList(joinPoint.getArgs());

        LogResquestAndResponse logs = infobloxLogsMapper.mapRequestResponsetoObject(logsMapper,paramList, infoProvider ,null, null );
        log.info("When=Before, User={}, Requester={}, Method={}, ParamList={}, Source= {}, Reference={} ", infoProvider.getCurrentUsername(),
                joinPoint.getSignature().toShortString(), paramList, infoProvider.getSourceSystem(), infoProvider.getReference());
    }

    @AfterReturning(pointcut = "execution(* com.tr.dco.fp.ipam.controller..*.*(..))", returning = "retVal")
    public void logAfter(JoinPoint joinPoint, ResponseEntity<?> retVal) {   
        List<Object> paramList =Arrays.asList(joinPoint.getArgs());
        LogResquestAndResponse logs = infobloxLogsMapper.mapRequestResponsetoObject(logsMapper,paramList, infoProvider ,retVal, null);
        List<LogResquestAndResponse> jsonList = new ArrayList<LogResquestAndResponse>();
        jsonList.add(logs);
        try{
        ObjectMapper mapper = new ObjectMapper();
        String jsonlogs = mapper.writeValueAsString(jsonList);
        saveToArongo(jsonlogs);
    } catch (JsonProcessingException e) {
        log.warn(e.getMessage());
    }}

    @AfterThrowing(pointcut = "execution(* com.tr.dco.fp.ipam.controller..*.*(..))", throwing = "ex")
    public void logError(JoinPoint joinPoint, Exception ex) {
        List<Object> paramList =Arrays.asList(joinPoint.getArgs());
        LogResquestAndResponse logs = infobloxLogsMapper.mapRequestResponsetoObject(logsMapper,paramList, infoProvider ,null, ex );
        List<LogResquestAndResponse> jsonList = new ArrayList<LogResquestAndResponse>();
        jsonList.add(logs);
            ObjectMapper mapper = new ObjectMapper();           
            String jsonlogs;
            try {
                jsonlogs = mapper.writeValueAsString(jsonList);
                saveToArongo(jsonlogs);
            } catch (JsonProcessingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }


    public void saveToArongo(String jsonArray) {
        //saving in db
}

当我进行 API 调用控制器类时。首先在方法被执行之前,然后是实际方法,然后是在抛出方法之后。在此之后再次调用之前方法,然后调用返回方法之后。无法指出为什么它被调用两次。需要帮忙。

标签: springspring-aop

解决方案


我解决了这个问题。在同一个包中包含一个异常处理程序类,在引发异常的情况下被调用,并且再次调用我的 before 方法。


推荐阅读