我正在开发一个spring MVC应用程序。当我尝试在我的控制器类中使用AnnotationConfigApplicationContext时,我收到以下错误。我不知道这个陈述究竟意味着什么。
@RequestMapping(value = "/generate", method = RequestMethod.POST)
public ModelAndView generateMappingFile(@ModelAttribute Mapping mapping)
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MappingFileGenerator mfg = ctx.getBean(MappingFileGenerator.class);
}
错误讯息 - >
java.lang.IllegalStateException:org.springframework.context.annotation.AnnotationConfigApplicationContext@116b3c0 has not been refreshed yet
有人可以解释一下这里出了什么问题吗?我正在使用Spring 4.0.1 ..我是spring mvc的新手。
答案 0 :(得分:8)
当您创建ApplicationContext
的新实例(无论哪种类型)时,您基本上是为ApplicationContext
中配置的每个bean创建新实例。这是第一次很好,它可能会工作第二次,并取决于bean的数量,豆类的类型将崩溃。由于上下文永远不会被破坏(直到应用程序崩溃并重新启动),您将遇到可能的内存问题,性能问题,奇怪的事务性问题等。
一般的经验法则是从不构造ApplicationContext
的新实例,而是使用依赖注入。
如果您真的想要访问ApplicationContext
,请在控制器中放置该类型的字段,并在其上添加@Autowired
。
@Controller
public class MyController {
@Autowired
private ApplicationContext ctx;
….
}
然后,您可以在方法中查找所需的bean。如果您使用ApplicationContext
作为bean的工厂,这可能很方便。如果您需要的所有豆子都是单身,那么最好简单地注入您需要的豆子。
@Controller
public class MyController {
@Autowired
private MappingFileGenerator mfg ;
….
}
现在Spring会注入MappingFileGenerator
,它可以在你的方法中使用。无需创建ApplicationContext
的新实例。
更多信息位于Spring Reference Guide。
答案 1 :(得分:2)
@ M.Deinum的评论将获得更多赞成。
考虑创建一个new ApplicationContext
来实例化一个新的(实例)应用程序。您是否希望每次调用此(或所述应用程序中的任何其他方法)时都这样做?不,你没有。
我猜你想,因为你需要在这种方法中访问ApplicationContext
。要做到这一点 - 即访问运行应用程序上下文(而不是创建一个新的),你想做
@Controller // or @Service / @Component / ... : tells Spring that this is a bean, and to inject the specified dependencies
class YourClass {
@Autowired // tells Spring that this object is a dependency should should be injected
ApplicationContext ctx;
@RequestMapping(value = "/generate", method = RequestMethod.POST)
public ModelAndView generateMappingFile(@ModelAttribute Mapping mapping) {
MappingFileGenerator mfg = ctx.getBean(MappingFileGenerator.class);
}
这里的关键是Autowired
annotation,它告诉Spring inject带注释的对象为dependency。
我强烈建议关注我所包含的链接(对于初学者),因为你在这里所做的事情非常强烈地表明你没有围绕DI是什么,为你做什么,直到你这样做,使用它可能会对你自己的目的起反作用。
答案 2 :(得分:0)
万一它对某人有所帮助,那么我在将新的URL映射添加到gradle项目中时遇到了这个问题,我错过了该URL的第一个斜杠,并导致测试中的这种“非法状态尚未刷新”