Reputation: 3660
Here is my class,
public class MyBusinessException extends RuntimeException {
@Autowired
private MessageSource messageSource;
private String errorCode;
private String messageInEnglish;
public MyBusinessException(String errorCode){
this.errorCode=errorCode;
this.messageInEnglish=messageSource.getMessage(this.code,null, Locale.ENGLISH);
}
}
This is an exception class.When I pass the errorCode
as a parameter to constructor it should populate the error message,That`s what I am looking for.Infact I want to instantiate the class like this
throw new MyBusinessException("MY-ERROR-CODE");//want to initiate like this(only one argument for constructor)
How to achieve something like this?
All these I have tried so far:
@PostConstruct
Upvotes: 3
Views: 3006
Reputation: 131326
throw new MyBusinessException("MY-ERROR-CODE");//want to initiate like this(only one argument for constructor)
You cannot use @Autowired
with objects that are not created by Spring.
I think that you should refactor your code to provide to MyBusinessException constructor all information that needs.
You don't need to couple it with Spring.
The logic that is Spring dependent :
@Autowired
private MessageSource messageSource;
...
messageSource.getMessage(this.code,null, Locale.ENGLISH);
could be moved to a Spring bean that will create a fully initialized MyBusinessException
instance.
Besides, messageSource.getMessage(this.code,null, Locale.ENGLISH)
may be required for other exceptions. Moving it this logic in a specific class makes sense.
@Bean
public class ExceptionFactory{
@Autowired
private MessageSource messageSource;
public MyBusinessException createMyBusinessException(String errorCode){
return new MyBusinessException(errorCode, messageSource.getMessage(this.code,null, Locale.ENGLISH));
}
}
You can note that createMyBusinessException()
provides a simple API for the clients : they need to pass only the error code String
to create the exception.
The MessageSource
dependency is a implementation detail that they don't need to bother with.
For example, this is enough :
throw exceptionFactory.createMyBusinessException("MY-ERROR-CODE");
Upvotes: 5
Reputation: 6571
Dependency Injection does only work for instances that are created by Spring.
Since you manually initialize your exception you need to inject the MessageSource
to the @Component
throwing this exception.
Then you could either pass the MessageSource
to the constructor of your MyBusinessException
or get the message in the desired language and pass this message to the constructor.
@Component
public class MyComponentDoingBusinessLogic {
private MessageSource messageSource;
@Autowired
public MyComponentDoingBusinessLogic(MessageSource messageSource) {
this.messageSource = messageSource;
}
public void someBusinessLogic() {
//Doing something
if (errorState) {
throw new MyBusinessException(yourErrorCode, messageSource);
}
}
}
Upvotes: 3
Reputation: 2691
You can't do it this way. An exception is constructed when it is thrown, which means that it won't get initialised by Spring. What you could do is to use a static method to get the current Spring application context, and get your bean from there.
Whether or not this is a clean solution is another issue, but you didn't ask about that.
Upvotes: 0
Reputation: 8839
You cannot use @Autowired
inside the ctor, as it was not yet initializaed by Spring.
The right way to do so, is to implement InitializingBean
, which is basically Spring's ctor, and there (afterPropertiesSet
method) you can use your injected fields.
Upvotes: 1