MaVVamaldo
MaVVamaldo

Reputation: 2535

Injected MessageSource is null

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:

  1. deleting the annotations and injecting the message source via xml configuration file
  2. implementing the MessageSourceAware interface
  3. trying to inject a 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

Answers (4)

tharindu_DG
tharindu_DG

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

Gauri Telang
Gauri Telang

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

Breand&#225;n Dalton
Breand&#225;n Dalton

Reputation: 1639

change basename to something like this:

<property name="basename" value="classpath:messages/messages" />

Upvotes: 0

Boris Treukhov
Boris Treukhov

Reputation: 17774

I think that you are examining the field values of a CGLIB class

See spring singleton bean fields are not populated update

A general note about autowiring

@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

Related Questions