2013-08-06 5 views
0

Мне интересно, какой лучший подход для уведомления о событиях EJB/Seam session о изменениях данных в компоненте, включенном в приложение.Как уведомить сеансы сеанса шва об измененных данных

В моем случае использования у меня есть центральная (прикладная область) планка seam2, которая связывается с различными службами, чтобы обновлять данные приложения. Как только что-то изменится, мне нужно уведомить все мои текущие сеансы пользователя об измененных данных, чтобы они могли забрать его, как только сможете. Каков наилучший способ достичь этого?

Я пробовал @RaiseEvent, подход @Observer от Seam, но, похоже, не представляется возможным уведомлять beans в SessionScope от ApplicationScope.

Я использую JEE5, Seam2, EJB3.0

Благодаря

+0

Можете ли вы переключиться на JEE 6? Это было бы очень легко с CDI beans (и вы могли бы отказаться от Seam, который считается устаревшим в пользу CDI) –

+0

К сожалению, сейчас это не вариант. – Richard

ответ

0

Если нашли решение, которое нуждается в небольшой трюк работать.

Прежде всего я создал два новых интерфейсы в моем проекте:

public interface IDataProvider { 

    public void register(IDataObserver observer); 

    public void unregister(IDataObserver observer); 
} 

public interface IDataObserver { 
    public void update(); 
} 

В качестве второго шага я реализовал два интерфейса в моей фасоли.

@Name(ApplicationBean.BEAN_NAME) 
@Scope(ScopeType.APPLICATION) 
public class ApplicationBean implements IDataProvider { 
    private Set<IDataObserver> observerList = new HashSet<IDataObserver>(); 

    @Override 
    public void register(IDataObserver observer) { 
     this.observerList.add(observer); 

    } 

    @Override 
    public void unregister(IDataObserver observer) { 
     this.observerList.remove(observer); 
    } 

    public void notifyAllObserver() { 
     for(IDataObserver observer : observerList) { 
      observer.update(); 
     } 
    } 
} 

@Name(SessionBean.BEAN_NAME) 
@Scope(ScopeType.SESSION) 
public class SessionBean implements IDataObserver { 

    @Create 
    public void init() { 
     // inject dependencies 
     injectBeans(); 

     // register at the dataserviceprovider to be notified about data changes 
     dataProviderService.register(this); 
    } 

    private void injectBeans() { 
     dataProviderService = (DataProviderService) Component.getInstance(
       DataProviderService.BEAN_NAME, ScopeType.APPLICATION); 
    } 

    @Destroy 
    public void shutDown() { 
     dataProviderService.unregister(this); 
    } 

    @Override 
    public void update() { 
     // grab data from 
    } 
} 

Обратите внимание, что этот подход работает только если вводить ваши детали шва через Component.getInstance(), а не через @in. В последнем случае вы всегда получите нуль для них, как только будет вызвано update()!

+0

Использование «классического» шаблона наблюдения не является хорошей идеей при работе с Seam-Components. Не рекомендуется ссылки на Seam-Components - все механизмы Seam не будут работать (например, http://seamframework.org/Documentation/CanIHoldAReferenceToASeamComponentSuchAsInAList). В любом случае - в вашем методе обновления вы можете получить экземпляр этого компонента в Seam-контексте. Просто используйте 'Component.getInstance (BEAN_NAME)' и делайте все на этом «новом» объекте. – MrD

+0

Еще одно примечание: метод, который вы вызываете для компонента в контексте Seam, не должен быть закрытым. Кажется, что прокси-сервер Seam не переносит частные методы. – MrD

+0

Спасибо за ваш совет, я вижу свою ошибку и соответствующим образом изменил код для инъекций. Я также хотел бы придерживаться стандартного механизма событий шва для реализации моего шаблона наблюдателя, но, к сожалению, я не смог запустить его между областями приложения и областью действия сеанса. Между областью применения фасоли она работает очень хорошо. – Richard

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

  • Нет связанных вопросов^_^