繁体   English   中英

Spring Boot @Autowired MessageSource 在一个类中有效,在另一个类中无效

[英]Spring Boot @Autowired MessageSource works in one classes and doesn't in another

我正在学习用于开发 web 应用程序的 Spring 引导框架(版本 2.0.7.RELEASE)。 当我尝试自动装配 MessageSource class 时,它适用于一个类,但不适用于另一个类:

这是我的 WebConfig class:

package net.local.mis.phog.config;
@Configuration
public class WebConfig implements WebMvcConfigurer {
    [...]
    @Bean
    public MessageSource messageSource() {
        // This is the only place around application where messageSource is created
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages");
        messageSource.setDefaultEncoding("UTF-8");

        return messageSource;
    }
    [...]
}

在 controller 类中一切正常,例如:

package net.local.mis.phog.controller;
@Controller
@Transactional
public class AlbumController {
    [...]
    @Autowired
    private MessageSource messageSource; (works fine)
    [...]
}

但是当我尝试在 model 类中注入 messagSource 时,它失败了:

package net.local.mis.phog.model;
@Component
public class AlbumModel {
    [...]
    @Autowired
    private MessageSource messageSource; (null)
    [...]
}

spring 中——组件在一个 class 中自动装配,但在另一个中没有自动装配Balaji Krishnan 说:“你没有使用 spring 来获取帐户实例——所以 spring 没有机会自动装配它”。 也许我应该做些类似的事情,但我不明白该怎么做。

谁能帮帮我。

谢谢你,米哈伊尔。

为了使Spring能够利用依赖注入,所有bean必须全部由Spring管理。 应该通过spring管理AlbumModel对象的创建,以便可以自动装配MessageSource 如果AlbumModel不应该由spring管理,并且您想自己创建对象(我怀疑是因为您使用@Component对其进行了注释),那么您也可以使用构造函数注入。

而您可以拥有以下内容:

package net.local.mis.phog.model;
@Component
public class AlbumModel {
    [...]

    private MessageSource messageSource; 
    [...]

    @Autowired
    public AlbumModel(MessageSource messageSource) {
        this.messageSource = messageSource;
    }
}

使用上述解决方案,当您手动创建AlbumModel ,可以传入MessageSource对象,该对象已经由调用类(例如,控制器或任何服务层类)自动连接。 但是,如果在春季之前管理AlbumModel创建,建议使用构造函数注入。 Spring贡献者的一篇文章中了解更多

谢谢你们的回答。

Amit Bera,我仅通过调用其构造函数来创建AlbumModel对象:

package net.local.mis.phog.controller;

@Controller
@Transactional
public class AlbumController {
    [...]
    @Autowired
    private JenreDao jenreDao;
    @Autowired
    private MessageSource messageSource;

    [...]
    @RequestMapping(value={"/album"},method=RequestMethod.GET)
    public String albumShowHandler(Model model,
                                   HttpServletRequest request,
                                   @RequestParam(value="jenreIdSelected") Long jenreIdSelected,
                                   @CookieValue(value="thumbnailOrder",defaultValue="ordDefault") String thumbnailOrder,
                                   [...]) {
        [...]
        ThumbnailOrderAux thumbnailOrderAux = new ThumbnailOrderAux(thumbnailOrder);
        JenreAux jenreAux = new JenreAux(jenreDao.getLstJenreModel(null,jenreIdSelected),jenreIdSelected);
        AlbumModel albumModel = new AlbumModel(jenreAux,thumbnailOrderAux);
        [...]

        model.addAttribute("albumModel",albumModel);

        return "album";
    }
    [...]
}

这是AdminModel构造函数的代码:

package net.local.mis.phog.model;

@Component
public class AlbumModel {
    private JenreAux jenreAux;
    private ThumbnailAux thumbnailAux;
    [...]

    public AlbumModel() {
        super();
    }
    public AlbumModel(JenreAux jenreAux,ThumbnailOrderAux thumbnailOrderAux) {
        super();

        this.jenreAux = jenreAux;
        this.thumbnailOrderAux = thumbnailOrderAux;
    }
    [...]
}

Nazeem,我在AlbumModel类中添加了@Component批注,希望可以注入MessageSource bean。 不幸的是事实并非如此。

我可以将MessageSource作为参数传递,即使我不对构造函数@Autowired进行注释,它也可以正常工作。 如果我理解正确的话,MessageSource bean被注入到AlbumController中,因为它是由Spring管理的,并且它没有注入到AlbumModel中,因为它不是由Spring管理的。 对? 如果是这样,我有什么办法让Spring管理AlbumModel对象?

我在 spring 3.1.1-RELEASE 旧应用程序上遇到了同样的问题。 在我的例子中,在调试期间我有两个不同的MessageResource对象,就好像 wold 已经被实例化了两次一样。

我已经解决了移动 bean 定义的问题:

<bean id="messageSource"
      class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

dispatcher-servlet.xml基于 xml 的配置文件到applicationContext.xml的配置文件。

换句话说,存在两个上下文应用程序上下文和调度程序 servlet 上下文 应用程序上下文是调度程序 servlet 上下文的父级(我猜想如果您的应用程序包含许多 servlet,那么许多 servlet 上下文可能存在于相同的应用程序上下文中)。

因此,在应用程序上下文中定义的 beans 对 servlet 上下文可见,但反之则不然 虽然 servlet 上下文包含那些与 MVC 特别相关的 bean,但应用程序上下文用于定义更广泛的 bean,如服务。

由于@Controller注释是@Component注释的:

@Component
public @interface Controller

我猜 Spring 在@Controller@Component中以不同的方式自动装配 bean,在上面提到的两个不同的上下文中寻找 bean。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM