簡體   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