0

I'm developing a spring web application. I have no XML configuration at all. The main class of the spring boot app is annotatd with a component scan which includes all the beans here listed.

Having this controller class:

@CrossOrigin
@RestController
@RequestMapping(value = "/documento/detail/tabs")
public class InfoController {

@Autowired
private DocDetailService detailService;

/**
 * SEC 26-28: Pricing e posizioni
 */
@LogMethod
@GetMapping(value = "/pricing/{numOperazione}", produces = MediaType.APPLICATION_JSON_VALUE)
private ResponseEntity<DetailPricingDTO> getDettagliPricingEPosizioni(
        @PathVariable(value = "numOperazione") final String numOperazione) throws DocumentNotFoundException {
    return ResponseEntity.ok(detailService.getDettagliPricing(numOperazione));
}

And @LogMethod defined like this:

@Documented
@Retention(RUNTIME)
@Target({ METHOD })
public @interface LogMethod {

}

With an aspect defined as follows, to log all method annotated with that request

@Aspect
@Component
@Scope("singleton")
public class LogEventAspect {

private final Logger log = LoggerFactory.getLogger(this.getClass());

@PostConstruct
public void postConstruct() {
    log.info("# LogMethod annotation ASPECT is enabled #");
}

@Pointcut("@annotation(LogMethod)")
public void logEventAnnotationPointCut() {
    // Method is empty as this is just a point-cut, the implementations are in the
    // advises.
}

@AfterThrowing(pointcut = "logEventAnnotationPointCut()", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
    log.error("Exception in {}.{}() with cause = \'{}\' and exception = \'{}\'",
            joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(),
            e.getCause() != null ? e.getCause() : "NULL", e.getMessage(), e);
}


@Around("logEventAnnotationPointCut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {

    // Log before execution
    if (log.isDebugEnabled()) {
        log.debug("Enter>>>: {}.{}() with argument[s] = {}", joinPoint.getSignature().getDeclaringTypeName(),
                joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
    }

    Object result = joinPoint.proceed();

    // log after execution
    if (log.isDebugEnabled()) {
        log.debug("Exit<<<: {}.{}() with result = {}", joinPoint.getSignature().getDeclaringTypeName(),
                joinPoint.getSignature().getName(), result);
    }

    return result;

}

}

The detailService in the controller is NULL. If I remove the @LogMethod the service is correctly initialized.
Also, if I use the @LogMethod in a @Service class instead of the @RestController, the autowiring of other beans does work. Why does this happen?

Gaetano Piazzolla
  • 1,388
  • 1
  • 16
  • 31
  • Does this answer your question? [Spring autowired bean for @Aspect aspect is null](https://stackoverflow.com/questions/9633840/spring-autowired-bean-for-aspect-aspect-is-null) – pvpkiran Mar 30 '20 at 11:10
  • I think not, i'm not using XML configuration. In addition, if I use that annotation on a service and not the controller, the autowiring works. – Gaetano Piazzolla Mar 30 '20 at 11:13
  • Make your controller method `public` instead of `private`. A proxy will be created by extending your controller. however as private methods cannot be overridden it will be called on the proxy instead of passing through to the actual instance having the dependencies. – M. Deinum Mar 30 '20 at 12:08
  • This does not answer my question. If I remove the @LogMethod The controller methods can be private and the autowired still works. – Gaetano Piazzolla Mar 30 '20 at 12:19
  • @M.Deinum **did** answer your question, just read carefully. Your `@LogMethod` makes Spring create a proxy because it needs the proxy for AOP. It works without the annotation because then no proxy is created. Go get it working with proxy and AOP, the method must be non-private, ideally public but protected or package-scoped also works with CGLIB proxies. But I am just elaborating a bit, the merits belong to M.Deinum. – kriegaex Mar 31 '20 at 11:32
  • Package scoped won't work here, only protected and public. – M. Deinum Mar 31 '20 at 11:45
  • I've tried it. M. Deinum is right, the problem is annotating the private method with the @LogMethod. But can you tell me why spring does not log any error? should it be forbidden to using AOP on private methods, at least an error should be generated.. am I wrong? anyway, do you think an answer to this question will be useful for another user? if yes please answer and I'll mark the answer as accepted. Otherwise thank you again, and sorry if I din't believe your answer in the first place. – Gaetano Piazzolla Mar 31 '20 at 18:30

0 Answers0