1

I work on spring boot 2 project and define the following code, but the messageSource always is null. I have autowired MessageSource in @service class, it works. Who can tell me WHY?

public class ApplicationException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    @Autowired
    private MessageSource messageSource;

}
Bendy Zhang
  • 451
  • 2
  • 10

1 Answers1

3

Autowiring works only in managed class (eg. annotated as @Component, @Service or defined in application context xml). ApplicationException is not managed by Spring container so it not even tries to inject that property. Try autowire your MessageSource in service class where you use this exception and pass it in constructor.

@Service
public class SomeService {
    private MessageSource messageSource;
    @Autowired
    public SomeService(@NonNull MessageSource messageSource) {
        this.messageSource = messageSource;
    }
    public void someMethod() {
        throw new ApplicationException(messageSource, "Some message");
    }
}
kemot90
  • 551
  • 3
  • 14
  • Yes, I follow your answer. But I always need to pass messageSource as the parameter to new ApplicationException. Do you have any solutions to fix this? – Bendy Zhang Sep 11 '18 at 08:23
  • You can use Spring AOP for additional action while exception handling like enrichment it with messages from MessageSource. Here's an example: https://stackoverflow.com/a/44738905/1694996 – kemot90 Sep 12 '18 at 06:10
  • Bingo, I missed AOP. I autowire MessageSource in ControllerAdvise class and then worked. Thanks for the lights of @kemot90 – Bendy Zhang Sep 12 '18 at 09:17
  • Or you could just add `SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this)` in your exception class constructor. Of course add your `@Autowired MessageSource messageSource` then as well. I hope that helps – Sebastian Forza Nov 09 '20 at 06:59
  • .. or you can create a new Exception instance by using a factory where you pass the message key (and the desired exception type?) to a factory method. This spring managed factory then creates an exception object for you by resolving the message from it's autowired message source and passing it to the ex constructor. This would be a possibility if you don't have control over the exception class, if it's e.g. from some third party lib. The factory could even throw the exception. E.g. `exFactory.createException("my.msg.key", MyAppException.class)`. Maybe there is already something out there. – Sebastian Forza Nov 09 '20 at 07:15