New updates:
Dec 31 2010 8:15 PM
Very dirty fix but this is how I have temporarily made the messageSource to work. I changed my Controller class to pass the 'messageSource' to Message class and am able to retrieve the messages. Please review the class definition below and let me know any more info that you may need to help. I really appreciate all the help you are providing.
Dec 31 2010 3 PM
As I could not succeed in configuring messageSource through annotations, I attempted to configure messageSource injection through servlet-context.xml. I still have messageSource as null. Please let me know if you need any more specific info, and I will provide. Thanks for your help in advance.
servlet-context.xml
<beans:bean id="message"
class="com.mycompany.myapp.domain.common.message.Message">
<beans:property name="messageSource" ref="messageSource" />
</beans:bean>
Spring gives the below information message about spring initialization.
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'message': replacing [Generic bean: class [com.mycompany.myapp.domain.common.message.Message]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [C:\springsource\tc-server-developer-2.1.0.RELEASE\spring-insight-instance\wtpwebapps\myapp\WEB-INF\classes\com\mycompany\myapp\domain\common\message\Message.class]] with [Generic bean: class [com.mycompany.myapp.domain.common.message.Message]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]]
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1c7caac5: defining beans [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.validation.beanvalidation.LocalValidatorFactoryBean#0,org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0,xxxDao,message,xxxService,jsonDateSerializer,xxxController,homeController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,tilesViewResolver,tilesConfigurer,messageSource,org.springframework.web.servlet.handler.MappedInterceptor#1,localeResolver,org.springframework.web.servlet.view.ContentNegotiatingViewResolver#0,validator,resourceBundleLocator,messageInterpolator]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@4f47af3
I have the below definition for message source in 3 classes. In debug mode, I can see that in class xxxController
, messageSource
is initialized to org.springframework.context.support.ReloadableResourceBundleMessageSource
. I have annotated Message class with @Component and xxxHibernateDaoImpl with @Repository. I also included context namespace definition in servlet-context.xml. But in Message
class and xxxHibernateDaoImpl
class, the messageSource
is still null.
Why is Spring not initializing messageSource in the two other classes though in xxxController
classes, it initializes correctly?
@Controller
public class xxxController{
@Autowired
private ReloadableResourceBundleMessageSource messageSource;
}
@Component
public class Message{
@Autowired
private ReloadableResourceBundleMessageSource messageSource;
}
@Repository("xxxDao")
public class xxxHibernateDaoImpl{
@Autowired
private ReloadableResourceBundleMessageSource messageSource;
}
<beans:beans
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="/resources/messages/messages" />
</beans:bean>
<context:component-scan base-package="com.mycompany.myapp"/>
</beans>
Spring does not know about those classes that you are getting a null value field from. You can tell Spring about them by defining them as beans in your app context or annotating the classes as @Component
The reason why your first class is getting autowired correctly is because that class is correctly annotated as @Controller
Try to refine your base-package. Don't let spring scan all your application class com.mycompany.myapp , (you will have a better startup time).
Suppose you have your controller class in a package : com.mycompany.myapp.controller and your service class (annotated with @component, @repository) in package com.mycompany.myapp.services
Add this to your [servlet-name]-servlet.xml (Dispatcher context file)
<context:component-scan base-package="com.mycompany.myapp.controller" />
In the other hand, open your servlet-context.xml (Supposed to be an application context loaded by contextloaderlistener) and add this :
<context:component-scan base-package="com.mycompany.myapp.services" />
followed by the declaration of your messageSource as you did.
You will have one messageSource injected every where it is autowired. It should work because stuff defined in Dispatcher-context-file can see other beans declared in application-context file(s) but not the opposite
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With