Question

Anyone knows how to inject a dependency to a @ControllerAdvice?

My @ControllerAdvice extends Spring's ResponseEntityExceptionHandler and implements no interfaces.

The @ControllerAdvice gets called correctly, but the @Autowired dependency is never injected. There are no startup injection errors, the dependency is simply null.

I guess it has to do with how Spring proxies the @ControllerAdvice with cglib so that the @Autowired annotation gets lost.

I tested by implementing an interface, so that Spring could create a JDK proxy but it didn't work either. Actually with an interface, it didn't even gets called at all... even if I also annotate the interface with @ControllerAdvice.

Is there a way to specify that Spring should use JDK proxies for that particular case?

EDIT: I'm using Spring 3.2.4.RELEASE, by the way.

Sample class:

@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {

    @Autowired(required = true)
    public AuditService auditService;

    @ExceptionHandler(value = { RuntimeException.class })
    public final ResponseEntity<Object> handleRuntimeException(Exception ex, WebRequest request) {
        // auditService is null here!
    }

}
Was it helpful?

Solution

In your case your bean is behind a CGLIB proxy. It creates a subclass of your bean and as the method has final modifier it can't change the behavior of the original ResponseEntityExceptionHandler class to insert a call to the bean behind - please check my other answer about CGLIB.

CGLIB proxy is a different object that delegates the method calls to the original bean.

Please note that it would not be possible to implement much of Spring functionality only with subclassing i.e. without this separation of objects. How would it work when singleton-scoped bean references a session-scoped bean - obviously there are many session-scope beans and only one singleton-scoped bean.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top