AnnotationConfigApplicationContext尚未刷新

时间:2014-09-15 07:06:49

标签: java spring spring-mvc

我正在开发一个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的新手。

3 个答案:

答案 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的第一个斜杠,并导致测试中的这种“非法状态尚未刷新”