Reputation: 2535
Framework: Spring 3.
I really can't understand why the message source injectend in a bean ends up always to be NULL.
Here's the snippets:
the servlet.xml
<context:annotation-config />
<context:component-scan base-package="com.myproject.controllers" />
<mvc:annotation-driven />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages/messages" />
<property name="cacheSeconds" value="0" />
</bean>
the class where the messageSource is injected
import com.myproject.controllers.forms.RegistrationForm;
@Component
public class RegistrationFormValidator implements Validator {
@Autowired
@Qualifier("messageSource")
private MessageSource messageSource;
//other stuff here...
}
here's the controller
@Controller
@SessionAttributes("userSearchForm")
public class UsersController extends PaginationController<ProfiledUser>{
@InitBinder(value="registrationForm")
public void initBinder(WebDataBinder binder)
{
binder.setValidator(new RegistrationFormValidator());
}
I have already tried the following:
ReloadableresourceBundleMessageSource
instead of using interface MessageSource
everything ends up in a epic fail ;-) How can I get the MessageSource properly injected?
Upvotes: 0
Views: 12069
Reputation: 9271
In the java configs class add the following beans.
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
return resolver;
}
@Bean
public MessageSourceAccessor messageSourceAccessor(MessageSource messageSource){
return new MessageSourceAccessor(messageSource, Locale.ENGLISH );
}
Then the MessageSourceAccessor
bean can be injected as follows
@Autowired
private MessageSourceAccessor msgs;
Get message strings as follows,
msgs.getMessage("controller.admin.save.success")
The message_en.properties
file should be inside /src/main/resources
folder. Add necessary properties file for other languages as well.
Hope this helps.
Upvotes: 0
Reputation: 1
I had similar issue when I tried to use the MessageSource in a custom Date Formatter.
The code AppDateFormatter
public class AppDateFormatter implements Formatter<Date> {
@Autowired
private MessageSource messageSource;
other stuff.....
private SimpleDateFormat createDateFormat(final Locale locale) {
final String format = this.messageSource.getMessage("date.format", null, locale);
final SimpleDateFormat dateFormat = new SimpleDateFormat(format);
dateFormat.setLenient(false);
return dateFormat;
}
}
This is what worked for me :
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
other stuff.....
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("Messages/Messages", "Messages/Labels");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(1);
return messageSource;
}
@Bean
public AppDateFormatter appDateFormatter(){
return new AppDateFormatter();
}
@Bean
public FormattingConversionService mvcConversionService() {
FormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addFormatter(appDateFormatter());
return conversionService;
}
}
Upvotes: 0
Reputation: 1639
change basename to something like this:
<property name="basename" value="classpath:messages/messages" />
Upvotes: 0
Reputation: 17774
I think that you are examining the field values of a CGLIB class
See spring singleton bean fields are not populated update
@Autowired
annotation is processed by AutowiredAnnotationBeanPostProcessor
which can be registered by specifying <context:annotation-config />
annotation in the respective spring configuration file(bean postprocessors work on a per container basis so you need to have different postprocessors for the servlet and for the application root context => you need to put <context:annotation-config />
both to the web app context and the dispatcher servlet configuration ).
Please note that @Autowired
annotation has required
property which is set as default to true, that means that if the autowiring process occurs Spring will check that exactly one instance of the specified bean exists. If the bean which fields are annotated with @Autowired
is a singleton then, the check will be performed during the application initialization.
update In this specific question the Validator
instance was not created by Spring at all, that is why no autowiring was performed and no initialization exceptions were thrown.
Upvotes: 1