2012-05-01 2 views
6

В спецификации указано, что контейнер CDI удаляет SFSB, когда контекст области видимости будет уничтожен. Как он точно удаляет EJB? Кажется, он не вызывает метод, аннотированный с помощью @Remove.Как CDI удаляет сессионный компонент с состоянием?

@Stateful 
public class CustomerDAOImpl implements CustomerDAO { 
    @PreDestroy 
    public void onDestroy() { 
     //This is getting called as expected 
    } 
    @Remove 
    public void deleteMyBean() { 
     //This is not getting called! 
    } 
} 

Таким образом, CDI технически выполняет то, что говорит спецификация. Вопрос в том, как справиться с вопросом, чтобы контейнер EJB удалял экземпляр? Благодарю.

ответ

2

Как говорит covener, это делается с использованием специфичного для реализации EJB API, который не является частью стандартного API EJB.

Как говорит covener, вызов @Remove NOT правильный путь. Методы @Remove вызывают код пользователя, а сообщают контейнер EJB для удаления EJB. Если вы хотите получить обратный вызов при удалении EJB, используйте @PreDestroy.

-1

Метод с @Remove аннотация должна быть вызвана явно клиентом, тогда контейнер вызовет метод, аннотированный с помощью @PreDestroy неявно, если он существует. После этого экземпляр компонента будет готов для сбора мусора.

Это единственный метод жизненного цикла, которым может управлять клиент, все остальные методы контролируются контейнером.

+0

Да, это нормальное поведение. Но как контейнер CDI удаляет EJB? Использует ли какой-либо недокументированный API запрос контейнера EJB для удаления? – RajV

+0

@RajV Мне не удалось найти его в спецификации, но вы можете найти полезную информацию в учебном пособии по Java EE, в разделе «Жизненный цикл состояния сессионного бина» на http://docs.oracle.com/javaee/5 /tutorial/doc/bnbmt.html –

+0

@downvoter Ухаживать за -1 –

3

Я думаю, что контейнер CDI нуждается в крючке в контейнере EJB, чтобы попросить его «сделать то, что вы сделали бы, если только метод @Remove только что завершил». Глядя на спецификацию EJB, EJB 2.1 имел механизм для этого в интерфейсах, которые вы должны были расширить.

По понятным причинам контейнер, вызывающий произвольный аннотированный метод @Remove для побочного эффекта, не рекомендуется.

+0

+1, но как нит, контейнер владеет реализацией EJBObject (у которого есть .remove, в основном это то, что CDI хочет использовать), но bean реализует SessionBean. –

+0

Это не ответ, а спекуляция. Если бы действительно был такой крючок, он был бы весьма специфичным для вендора. Как может такая реализация, как Weld, сделать это в общем виде. – RajV

+0

Вопрос не в том, что, как сварное соединение является портативным. Для сварки специально требуется контейнер для обеспечения всех видов реализации интерфейсов, включая SessionObjectReference # remove – covener

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