AnnotationConfigApplicationContext has not been refreshed yet - what's wrong?
Asked Answered
S

4

33

My very basic spring application stopped working and I can't understand what's happened. pom.xml:

<properties>
    <spring.version>4.1.1.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>

Config class:

@Configuration
public class MyConfig {

@Bean
public HelloWorld helloWorld() {
         return new HelloWorld();
    }
}

Bean class:

public class HelloWorld {
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }
    public String getMessage() {
         return message;
    }
}

Entry point of application:

public class MainApp {
public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.register(MyConfig.class);
    HelloWorld bean = ctx.getBean(HelloWorld.class);
    bean.setMessage("ladjfaj");
    System.out.println(bean.getMessage());
}
}

And I'm getting an error

Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@6ebf8cf5 has not been refreshed yet at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:943) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:967) at com.nikolas.config.MainApp.main(MainApp.java:12)

Shunt answered 9/2, 2015 at 7:31 Comment(0)
T
34

You have to call ctx.refresh() before you can call ctx.getBean(HelloWorld.class);

Tergal answered 9/2, 2015 at 7:34 Comment(3)
Thanks, it works! Is it necessary to call ctx.registerShutdownHook(); for proper schutdown the container?Shunt
@Shunt I do not think so.Tergal
This link can be useful docs.spring.io/spring-framework/docs/current/javadoc-api/org/…Shunt
G
17

If you dont want to call ctx.refresh() explicitly, just initialize ApplicationContext like this: new AnnotationConfigApplicationContext(MyConfig.class), then configuration will be registered and refreshed implicitly

Gunas answered 5/11, 2019 at 12:56 Comment(0)
S
3

Just in case someone has a similar issue and can´t relate directly to the example above, this may help:

I ran into the problem when I had one of my repositories outside of the folder that was included in

@EnableJpaRepositories(basePackages = {"com.myproject.repositores"})

Which lead to this first exception:

Description: Field profileRepository in com.myproject.featurepackage.config.ProfileService required a bean of type 'com.myproject.featurepackage.ProfileRepository' that could not be found. The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true)

When I afterwards accessed the ApplicationContext to instanciate a bean, I ran into the error

org.springframework.context.annotation.AnnotationConfigApplicationContext@4983159f has not been refreshed yet

Simulation answered 22/9, 2020 at 9:27 Comment(0)
T
0

Although spring context.refresh() would indeed solve this issue, I want to explain why exactly refresh() solves the problem.

The refresh itself is just a phase, on which, roughly, ApplicationContext is initializing and preparing for use. There are multiple important things that happen during the refresh phase, such as

  • Bean Definitions Loading. That basically means that the context loads bean definitions from configuration files or annotations.

  • Beans Creation and wiring (@Autowired)

  • Lifecycle callbacks invocation (For instance @PostConstruct methods, and init methods of InitializingBean).

  • and other

It is a lot more complicated than that, but in general, that is what happens.

So the above may imply the context itself is refreshed only once (and it is the case for some application contexts, like GenericApplicationContext), for most application contexts refresh can happen multiple times. It is an intended feature to allow for more flexible configuration.

So, to make it clear - if refresh have not been run at all, then the beans are guaranteed to be uninitialized. Therefore, spring, be default, if the refresh has not run previously at all, will discard all the attempts to get any bean.

Hope now it makes more sense, have a nice day :)

Tierell answered 25/7, 2024 at 13:45 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.