Jak działa interfejs Lifecycle na wiosnę? Czym są „najwyższy poziom fasoli singleton”?

W wiosennym javadoc jest powiedziane, że „interfejs cyklu życia jest obsługiwany tylko na fasolach singleton najwyższego poziomu”. TutajURL

MójLifecycleBeanTest.xml opisuje fasolę w następujący sposób:

<beans ...>
    <bean id="lifecycle" class="tests.LifecycleBean"/>
</beans>

więc wygląda wystarczająco „topish” i „singletonish”.

Co to znaczy? Jak sprawić, by Spring wiedział o implementacji fasoliLifecycle i coś z tym zrobić?

Załóżmy, że moja główna metoda wygląda na wiosnę

public static void main(String[] args) {
    new ClassPathXmlApplicationContext("/tests/LifecycleBeanTest.xml").close();
}

więc tworzy instancję kontekstu, a następnie natychmiast ją zamyka.

Czy mogę utworzyć fasolę w mojej konfiguracji, co opóźniaclose() wykonanie, aż aplikacja wykona wszystkie czynności? Więc ten wątek głównej metody czeka na zakończenie aplikacji?

Na przykład następujący fasola nie działa w sposób, w jaki myślałem. Anistart() niestop() jest nazywany.

package tests;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.Lifecycle;

public class LifecycleBean implements Lifecycle {

    private static final Logger log = LoggerFactory.getLogger(LifecycleBean.class);

    private final Thread thread = new Thread("Lifecycle") {
        {
            setDaemon(false);
            setUncaughtExceptionHandler(new UncaughtExceptionHandler() {

                @Override
                public void uncaughtException(Thread t, Throwable e) {
                    log.error("Abnormal thread termination", e);
                }
            });
        }

        public void run() {
            for(int i=0; i<10 && !isInterrupted(); ++i) {
                log.info("Hearbeat {}", i);
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    return;
                }
            }
        };
    };


    @Override
    public void start() {
        log.info("Starting bean");
        thread.start();
    }

    @Override
    public void stop() {
        log.info("Stopping bean");
        thread.interrupt();
        try {
            thread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return;
        }
    }

    @Override
    public boolean isRunning() {
        return thread.isAlive();
    }

}

AKTUALIZACJA 1

Wiem, że mogę czekać na kod w kodzie. Interesujące jest zaczepienie się w Spring.

questionAnswers(5)

yourAnswerToTheQuestion