Spring @Autowired messageSource在Controller中工作但在其他类中没有?

时间:2010-12-31 01:32:01

标签: java spring annotations

新更新: 2010年12月31日下午8:15
非常脏的修复,但这是我暂时使messageSource工作的方式。我更改了我的Controller类,将'messageSource'传递给Message类,并且能够检索消息。请查看下面的课程定义,让我们了解您可能需要提供帮助的更多信息。我非常感谢你提供的所有帮助。

2010年12月31日下午3点
由于我无法通过注释成功配置messageSource,因此我尝试通过servlet-context.xml配置messageSource注入。我仍然将messageSource设为null。如果您需要更具体的信息,请告诉我,我会提供。感谢您的帮助。

servlet-context.xml
<beans:bean id="message"
    class="com.mycompany.myapp.domain.common.message.Message">
    <beans:property name="messageSource" ref="messageSource" />
</beans:bean>

Spring提供了有关spring初始化的以下信息。

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


我在3个类中对消息源有以下定义。在调试模式下,我可以看到在课程xxxController中,messageSource被初始化为org.springframework.context.support.ReloadableResourceBundleMessageSource。我在@Component中注释了Message类,在@Repository中注释了xxxHibernateDaoImpl。我还在servlet-context.xml中包含了上下文命名空间定义。但是在Message类和xxxHibernateDaoImpl类中,messageSource仍为空。

为什么Spring没有在xxxController类的其他两个类中初始化messageSource,它是否正确初始化?

@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>

2 个答案:

答案 0 :(得分:4)

Spring不知道那些从中获取空值字段的类。您可以通过在应用程序上下文中将它们定义为bean或将类注释为@Component

来告诉Spring它们。

您的第一堂课正确自动装配的原因是因为该班级被正确注释为@Controller

答案 1 :(得分:2)

尝试优化您的基础包。不要让spring扫描所有应用程序类com.mycompany.myapp,(你将有更好的启动时间)。

假设您的控制器类在一个包中:com.mycompany.myapp.controller 和com.mycompany.myapp.services包中的服务类(用@component,@ owner注释)

将此添加到您的[servlet-name] -servlet.xml(Dispatcher上下文文件)

<context:component-scan base-package="com.mycompany.myapp.controller" />

另一方面,打开你的servlet-context.xml(假设是contextloaderlistener加载的应用程序上下文)并添加:

<context:component-scan base-package="com.mycompany.myapp.services" />

然后像你一样声明你的messageSource。

您将在每个自动装配的位置注入一个messageSource。它应该工作,因为在Dispatcher-context-file中定义的东西可以看到在应用程序上下文文件中声明的其他bean但不是相反的