【问题标题】:Spring @Autowired messageSource working in Controller but not in other classes?Spring @Autowired messageSource 在 Controller 中工作但在其他类中不工作?
【发布时间】:2010-12-31 01:32:01
【问题描述】:

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

2010 年 12 月 31 日下午 3 点
由于无法通过注解配置messageSource,我尝试通过servlet-context.xml 配置messageSource 注入。我仍然有 messageSource 为空。如果您需要任何更具体的信息,请告诉我,我会提供。提前感谢您的帮助。

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 没有在其他两个类中初始化 messageSource 而在 xxxController 类中初始化正确?

@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 声明这些类的?
  • 是的。我已将这些课程宣布为春季。请参阅上面的更新定义。

标签: java spring annotations


【解决方案1】:

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

来告诉 Spring

您的第一个类正确自动装配的原因是该类被正确注释为@Controller

【讨论】:

  • 请查看带有@Repository/@Component 注释和servlet-context.xml 的更新类。 messageSource 仍然为空。我怀疑这可能是 servlet-context.xml 中的定义顺序。因此,我在 messageSource 定义之后放置了组件扫描标记。问题仍然没有解决。我看到 xxxDao 和 xxxController 在 messageSource 之前首先实例化调试消息(粘贴在下面)。不确定这是否相关。
  • INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - 在 org.springframework.beans.factory.support.DefaultListableBeanFactory@5883914b 中预实例化单例:定义 bean [org.springframework.web. servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0,...,xxxDao,message,xxxService,jsonDateSerializer,xxxController,homeController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,...0,validator,resourceBundleLocator,messageInterpolator];父级:org.springframework.beans.factory.support.DefaultListableBeanFactory@3f5ebf57
  • INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - 在 org.springframework.beans.factory.support.DefaultListableBeanFactory@5883914b 中预实例化单例:定义 bean [org.springframework.web. servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0,..., xxxDao,message,xxxService,jsonDateSerializer,xxxController,homeController, ..., tilesConfigurer,messageSource,org.springframework.web.servlet.handler.MappedInterceptor#1,.. ., 验证器,resourceBundleLocator,messageInterpolator];父级:org.springframework.beans.factory.support.DefaultListableBeanFactory@3f5
  • @Jayaprakash:请不要将此类信息放入 cmets;最好将其编辑到您的问题中。 (此外,它触发了 SO 格式化 cmets 的“问题”,使它们更难阅读。)
  • 对不起,关于那个。我没有意识到格式问题。后来当我试图编辑它时,其他重叠的链接进来了。我以后会注意的。
【解决方案2】:

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

假设你的控制器类在一个包中:com.mycompany.myapp.controller 以及 com.mycompany.myapp.services 包中的服务类(使用 @component、@repository 注释)

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

<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 中定义的东西可以看到在 application-context 文件中声明的其他 bean,但不是相反

【讨论】:

  • 感谢您回复此主题。我首先定义了组件扫描,然后是 servlet-context.xml 中的 messageSource 定义。你认为我应该颠倒顺序以确保 Spring 在扫描组件时有可用的 messageSource 吗?这是否意味着组件扫描应该在最后完成,当所有其他 bean 都在 servlet-context.xml 中定义时?提前感谢您的帮助
  • 我尝试在 servlet-context.xml 中的 messageSource 定义之后移动组件扫描。但它仍然没有解决问题:(
  • 尝试更具体地说明您为组件扫描提供的内容。我已经更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 2022-07-22
  • 1970-01-01
相关资源
最近更新 更多