2015-07-11 2 views
0

У меня есть контекст пружины, в которой мы имеем Runnable бобы стали выглядеть примерно так:@PreDestroy не вызывается для Runnable

public void startChildAndWait(Class type) { 
    BaseMyDispatcher child = appContext.getBean(type); 
    child.initialize(this); //The child references its parent during run method 
    new Thread(child).start(); 
    synchronized(LOCK_OBJECT) { 
    LOCK_OBJECT.wait(someTime); 
    } 
} 

Класс BaseMyDispatcher является абстрактным классом и SampleRunnableX являются реализациями, которые с областью прототипа , базовый класс в основном имеет метод @PostConstruct и метод @PreDestroy (основная функция которого заключается в том, чтобы вызвать уведомление в LOCK_OBJECT) и, конечно, метод Run

Моя проблема заключается в том, что вызывается метод PostConstruct, но когда Метод запуска завершает объект, кажется, не уничтожен, поэтому метод PreDestroy равен n ot вызван, и я застрял в ожидании у родителя на LOCK_OBJECT

Код вызывается функцией внутри родительского Runnable (который выполняется внутри ThreadPoolExecutor и запускается (последовательно) несколькими дочерними элементами с тем же методом startChildAndWait, проходящим каждый раз, когда различного класса:

startChildAndWait(SampleRunnable1.class); 
if(run2IsRequired && lastExitCode == 100) {//runIsRequired are booleans 
    startChildAndWait(SampleRunnable2.class); 
} 
if(run3IsRequired && lastExitCode == 100) {//lastExitCode is an integer 
    startChildAndWait(SampleRunnable3.class); 
} 

Так что же делать, чтобы метод PreDestroy вызывал завершение дочернего потока?

ответ

0

@PreDestroy Метод обратного вызова будет вызываться, когда ваше приложение выключится, вам необходимо зарегистрировать привязку остановки к JVM и закрыть контекст приложения в нем при выходе из JVM.

//Create applicationContext 
final ApplicationContext appContext = 

//register ashutdown hook on application context 
Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { 
     appContext.close(); 
    }}); 

Если вы хотите выполнить некоторый код, когда дочерний поток завершается, лучше положить его в конце методы выполнения (резьба сам).

+0

Спасибо за оба ответа, причина, по которой я пытался это сделать, - вызвать метод destroy в базовом классе и сохранить расширенный класс в чистоте (т. Е. Не помещать код завершения кода в методе запуска). Я работаю так, как надеялся –

+0

Я решил сделать это через aspectj ... У меня есть точка вокруг выполнения метода run и может сделать для него новую аннотацию –

1

От the documentation:

В отличие от других областей, Spring не управляет полным жизненным циклом прототипа боба: контейнер конкретизирует, настраивает и иным образом собирает прототип объекта, а руки его к клиент, без дальнейшей записи этого экземпляра прототипа. Таким образом, хотя методы обратного вызова жизненного цикла инициализации вызываются на всех объектах независимо от области видимости, в случае прототипов сконфигурированные обратные вызовы жизненного цикла разрушения не вызываются.

Если вы хотите что-то произойдет, когда метод run() завершается, поставить этот код в конце метода run().

Смежные вопросы