我们有一个使用默认ApplicationContext运行良好的SpringApplication,但我们有一个场景需要刷新上下文,默认上下文不允许我们这样做。我将主要的Application类更新为:
// package and import lines not shown here but are included in original source
@ComponentScan("edge")
@EnableAutoConfiguration
@Configuration
@EnableTransactionManagement
@EnableAsync
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setApplicationContextClass(AnnotationConfigWebApplicationContext.class);
app.run(args);
}
使用此代码,调用app.run(args)会产生以下堆栈跟踪:
Exception in thread "main" java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext
at org.springframework.context.support.AbstractRefreshableApplicationContext.getBeanFactory(AbstractRefreshableApplicationContext.java:170)
at org.springframework.boot.context.event.EventPublishingRunListener.registerApplicationEventMulticaster(EventPublishingRunListener.java:70)
at org.springframework.boot.context.event.EventPublishingRunListener.contextPrepared(EventPublishingRunListener.java:65)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
at edge.server.Application.main(Application.java:43)
单步执行SpringApplication.run(),我注意到上下文的BeanFactory为null。如果我删除行app.setApplicationContextClass(AnnotationConfigWebApplicationContext.class)
,从而将应用程序设置为使用默认上下文,则代码会一直运行到我们调用refresh()的位置。该电话会导致:
java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once
有没有人以我描述的方式在SpringApplication中使用AnnotationConfigWebApplicationContext并让它工作?如果是这样,你有任何建议让这个工作?我已经尝试过在调用app.run()之前手动创建BeanFactory的方法,但似乎没有任何公共方法可以做到这一点。提前感谢您提供的任何帮助!
编辑以澄清:
感谢迄今为止的评论和答案。我应该在我的原始帖子中更明确地说明需要刷新ApplicationContext和我尝试使用AnnotationConfigWebApplicationContext的场景。我们有一些代码在服务器启动后运行,我们用于备份和恢复,这涉及修改我们正在使用的JpaRepositories的内容。我的理解是,在运行此代码之后,我们需要刷新ApplicationContext以便再次调用所有init方法。
尝试使用默认上下文类(AnnotationConfigEmbeddedWebApplicationContext,GenericApplicationContext的子类)执行此操作会抛出我之前提到的IllegalStateException(GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once
)。该异常促使我尝试将上下文显式设置为AnnotationConfigWebApplicationContext,后者是AbstractRefreshableApplicationContext的子类。我的假设是我需要应用程序使用AbstractRefreshableApplicationContext才能成功多次调用refresh方法。有没有办法让我上面的代码工作,或者我应该采取哪些替代方法,以便我们多次刷新上下文?
答案 0 :(得分:0)
您正在使用已经为您执行此操作的Spring Boot,您只是使它过于复杂。将您的课程更改为以下内容。
@EnableAsync
@EnableScheduling
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
确保它位于edge
包中,并确保您具有启用Web应用程序的spring-boot-starter-web
依赖项。没有必要自己搞乱上下文类。