How to start SpringApplication using AnnotationConfigWebApplicationContext?

We have a SpringApplication that works great with the default ApplicationContext, but we have a scenario where we need to update the context, and the default context prevents us from doing this. I've updated our main application class to look like this:

// 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);
    }

      

With this code calling app.run (args), the following stack trace is obtained:

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)

      

With SpringApplication.run () I noticed that the BeanFactory context is null. If I remove the line app.setApplicationContextClass(AnnotationConfigWebApplicationContext.class)

, thereby setting the application to use the default context, the code runs until we call refresh (). This call results in:

java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once

      

Has anyone used AnnotationConfigWebApplicationContext in SpringApplication in the order I described and did it work? If so, do you have any job offers? I've tried looking for ways to manually create the BeanFactory before calling app.run (), but there doesn't seem to be any public methods for that. Thanks in advance for the help provided!

Edit for clarification:

Thanks for the comments and responses. I should have been more explicit in my original post regarding a scenario that requires an ApplicationContext update and my attempt to use AnnotationConfigWebApplicationContext. We have a code that runs after the server starts, which we use for backup and restore purposes, which is related to changing the content of the JpaRepositories used. I understand that after running this code, we need to update the ApplicationContext in order to call all our init methods again.

Attempting to do this using the default context class (AnnotationConfigEmbeddedWebApplicationContext, a subclass of GenericApplicationContext) throws the IllegalStateException I mentioned earlier ( GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once

). This exception caused my attempt to explicitly set the context in the AnnotationConfigWebApplicationContext, which is a subclass of AbstractRefreshableApplicationContext. My guess was that I need an application to use AbstractRefreshableApplicationContext in order to successfully make multiple calls to the update method. Is there a way to get the code I have above to work, or is there some alternative approach I should take that will allow us to update the context multiple times?

+3


source to share


1 answer


You are using Spring Boot which already does this for you, you are just making it too complex. Change your class to the following.

@EnableAsync
@EnableScheduling
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

      



And make sure it is in the package edge

and make sure you have a dependency spring-boot-starter-web

that allows the web app. No need to mess with the context class.

0


source







All Articles