[英]Spring @Autowired messageSource working in Controller but not in other classes?
[英]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.