Card 05/ 06

WalkthroughDifficulty: Intermediate1 min

One Bean's Life, Start to Finish

RideDispatcher depends on RideLog. Both are beans, and running the whole thing shows the order the container actually follows — not the order you might guess.

java
package rides;

@Component
class RideLog {
    RideLog() { System.out.println("0. RideLog instantiated (a dependency)"); }
}

@Component
class RideDispatcher {
    private final RideLog log;

    RideDispatcher(RideLog log) {
        this.log = log;
        System.out.println("1. RideDispatcher instantiated, RideLog already populated");
    }

    @PostConstruct
    void init() { System.out.println("2. initialized (ready)"); }

    void dispatch() { System.out.println("3. dispatching a ride"); }

    @PreDestroy
    void shutdown() { System.out.println("4. destroyed"); }
}

Running it

Step 1 of 2

Start the context

java
var context = new AnnotationConfigApplicationContext(LifecycleConfig.class);
RideDispatcher dispatcher = context.getBean(RideDispatcher.class);
dispatcher.dispatch();

Close it

java
context.close();
text
0. RideLog instantiated (a dependency)
1. RideDispatcher instantiated, RideLog already populated
2. initialized (ready)
3. dispatching a ride
4. destroyed
run in a container, Spring Framework 6.1.14

Five phases, in order: instantiate the dependency first, so it exists to hand over; populate — RideDispatcher's constructor already receives a fully built RideLog; initialize, where @PostConstruct runs, once every property is set and not before; ready, where the bean does its actual job; and destroy, which only runs at all because this bean is a singleton and the context was closed cleanly.