2009-12-10 1 views
1

Возможно ли, чтобы контейнер ввел один и тот же экземпляр компонента сеанса с состоянием в несколько других сессионных компонентов с состоянием?Можно ли вставлять один экземпляр сеанса с включенным состоянием в несколько других сессионных компонентов?

Учитывая следующие классы:

@Stateful 
public class StatefulTwoBean implements StatefulTwo { 

    @EJB 
    private StatefulOne statefulOne; 

} 

@Stateful 
public class StatefulThreeBean implements StatefulThree { 

    @EJB 
    private StatefulOne statefulOne; 

} 

В приведенном выше примере, StatefulTwoBean и StatefulThreeBean каждый получить вводили свой собственный экземпляр StatefulOneBean.

Можно ли сделать контейнер впрыскивать же экземпляр из StatefulOneBean в обоих StatefulTwoBean и StatefulThreeBean?

+0

Каков ваш сервер приложений. – Bozho

+0

@ Божо зачем беспокоиться? –

+2

@Pascal, хорошо, я когда-то изучал подобную проблему и обнаружил, что этот WebLogic (если я правильно помню) обладает некоторой способностью достигать того, чего он хочет. Затем я использовал Glassfish (который не мог). Так что, если его сервер приложений - это стеклянная рыба, я мог бы посмотреть в кодовой базе и найти что-то, что вызовет его проблему :) – Bozho

ответ

2

Проблема заключается в том, что состояния Stateful beans arentances выделяются путем дифференцирования клиентов, которые их называют. Glassfish (и, возможно, другие) не распространяют эту разницу на впрыскиваемые бобы. Спецификация EJB, насколько я помню, не совсем понятна.

Итак, ваше решение заключается в реализации дифференциации самостоятельно. Как достичь этого. Я не притворяюсь, что это самое красивое решение, но оно сработало. - мы сделали это, поставив фасад (уже сам по себе EJB) (я называю его фасад, хотя и не полностью покрывает рисунок фасада) перед всей нашей EJBs, со следующим кодом:

public Object call(Object bean, 
     String methodName, 
     Object[] args, 
     Class[] parameterTypes, 
     UUID sessionId) throws Throwable { 

    //find the session 
    SessionContext sessionContext = SessionRegistry.getSession(sessionId); 
    //set it as current 
    SessionRegistry.setLocalSession(sessionContext); 
    ..... 
} 

Важным параметром является sessionId - это то, о чем знают как клиент, так и сервер, и идентифицирует текущее изображение между ними.

На клиенте мы использовали динамический прокси для вызова этого фасада. Таким образом, вызовы выглядят так: getBean(MyConcreteEJB.class).someMethod(), метод getBean создал прокси-сервер, так что вызывающим абонентам не нужно было знать о фасонных компонентах.

SessionRegistry был

private static ThreadLocal<SessionContext> localSessionContext = new 
    ThreadLocal<SessionContext>(); 

И SessionContext была просто карта обеспечение set(key, value) и get(key)

Так что теперь, вместо того, чтобы использовать @Stateful бобов, чтобы сохранить свое состояние, вы можете использовать SessionContext.

2

В EJB3.1 вы можете создать свой bean-компонент StatefulOne как singleton (используя аннотацию @Singleton), давая вам желаемую семантику. JBoss должен уже поддерживать эту аннотацию (они написали стандарт).

+0

Wim scope делает этот синглтон? Широкое приложение или привязано к клиенту, как фаза состояния? – Sylar

+1

@Sebastian: Синглтон-бобы определены как имеющие широкое применение.Для области сеанса, как вы уже упоминали, вы должны использовать сеансовые компоненты. – jawi