Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving messageSource to applicationContext causes the default messageSource not to be visible in dispatcher-servlet context

I have a webapp in which I define the basic dispatcher-servlet context in web.xml and it loads the applicationContext.

I had messageSource defined in dispatcher-servlet and was injecting it to controllers fine.

I also have my services defined in applicationContext and I can inject them into my controllers (defined in dispatcher-servlet context).

But when I moved my definition for messageSource to the applicationContext so that some services could resolve messages the dispatcher-servlet context shows that it's not finding a messageSource bean and is using the default, thus the controllers get the wrong bean injected.

Any idea why the messageSource definition in applicationContext wouldn't be visible to the dispatcher-servlet context?


I see that my messageSource bean is loaded in the applicationContext section of the logs:
2058 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Creating shared instance of singleton bean 'messageSource'
2058 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Creating instance of bean 'messageSource'
...
2082 [main] DEBUG org.springframework.web.context.support.XmlWebApplicationContext  - Using MessageSource [mycommons.spring.ResourceBundleMessageSourceWithDefaultResolution: basenames=[messages]]


I see this log in the loading of dispatcher-servlet:

3858 [main] DEBUG org.springframework.web.context.support.XmlWebApplicationContext  - Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@55611ed3]
like image 789
David Parks Avatar asked Mar 02 '11 10:03

David Parks


2 Answers

This is just the way it works. The messageSource bean must be defined in the context in which it is to be used. It will not be "inherited" from parent context to child.

This is a bit of a throwback to the early days of Spring 1.x, and has never really been changed since.

There are a number of "magic beans" that must be resident directly in the servlet appcontext, and this is one of them.

like image 89
skaffman Avatar answered Nov 18 '22 15:11

skaffman


Today I found "another" solution that works (for me it works in Spring 3.1 but I assume it will work in earlier versions as well, the parent attribute has been around for a while now). It will still create 2 beans, but not require you to add the whole bean definition a second time in the xxx-servlet.xml file:

In your applicationContext.xml:

<bean id="baseMessageSource" class="org.springframework...YourMessageSourceClass">
   ...
</bean>

In your xxx-servlet.xml:

<bean id="messageSource" parent="baseMessageSource" />

The second reference will simply "clone" the base bean from your application context and make it available to your servlet/controllers etc. This way, you can even override parts of your message source configuration in the servlet.

like image 1
NilsCodes Avatar answered Nov 18 '22 14:11

NilsCodes