2012-04-16 2 views
0

저는 vaadin + spring IOC + google guava eventbus를 사용합니다. Guava eventbus를 싱글 톤으로 사용하는 것이 좋습니다. 하지만 그렇게 할 때 다음과 같은 문제가 있습니다. Google 구아바 싱글 톤 이벤트 버스가 여러 번 발동합니다.

  • 의 내가 동시에 3 개 개의 다른 브라우저에서 응용 프로그램을 실행, 그래서 난 내 응용 프로그램의 3 개 가지 경우를 가정 해 봅시다.

  • 예를 들어 하나의 브라우저에서 버튼을 누르고 이벤트를 실행하면 @subscribe 주석이있는 관련 리스너 메소드가 3 회 호출됩니다.

eventbus를 싱글 톤으로 사용하기 때문에 예상되는 정상적인 동작입니까? 여기에 무슨 일이 일어나지 않으면? MainController는 스프링은 사용자 정의 angel이라는 응용 프로그램 범위

class MainController{ 
    public MainController() throws DAOException, Exception { 
    EventBusFactory.getEventBusInstance().register(this); 
    } 

    @Subscribe 
    public void addFacetEvent(FacetAddedEvent event) throws DAOException { 
    getTreeTableView().addToList(event.getData()); 
    } 
} 

class EventBusFactory{ 
    public static EventBus getEventBusInstance() { 
     if(eventBus==null){ 
      eventBus=new EventBus(); 
     } 
     return eventBus; 
    } 
} 

나는 또한 내가 구아바 eventbus 또는 구아바 GWT 이벤트 버스를 사용한다 angel이라는 주저 P.s와 콩을 관리?

감사

+0

소리가납니다 ... 이상하고 예상치 못한 소리입니다. 청취자가 세 번 등록 _ 했습니까? 또는 이벤트가 세 번 게시됩니까? –

+0

@Louis Wasserman 구독 주석이있는 내 메소드는 3 번 호출되지만 이벤트는 한 번만 게시됩니다. – Spring

+0

어떻게/어디서 리스너를 등록합니까? – Ray

답변

3

짧은 답변 :이 구성 (당신이 하나의 EventBus로 관리 세 angel이라는 응용 프로그램 및 따라서 세 MainController 인스턴스가)에서 정상 및 예상되는 동작입니다. angel이라는 사용자 정의 응용 프로그램 범위으로


this Vaadin addon에서 범위를 찾으시는 것입니까?

어쨌든,이 같은 상황 가진 프로토 타입 범위의 MainController 콩 및 angel이라는 앱을 재현 간단합니다

public class SandpitApplication extends Application { 
    private static final long serialVersionUID = 1L; 
    private static final Logger log = Logger.getLogger(SandpitApplication.class); 

    // https://vaadin.com/wiki/-/wiki/Main/Spring%20Integration#section-Spring+Integration-SpringContextHelperClass 
    private SpringContextHelper ctx; 

    @Override 
    public void init() { 
    // vaadin stuff 
    setTheme("common"); 
    final Window mainWindow = new Window("Vaadin Sample Application"); 
    setMainWindow(mainWindow); 

    // get your bean from spring 
    log.info("start [email protected]" + Integer.toHexString(hashCode())); 
    ctx = new SpringContextHelper(this); 
    // create application-wide bean 
    final MainController mainController = ctx.getBean("mainController"); 

    mainWindow.addComponent(new Button("click to post", new Button.ClickListener() { 
     @Override public void buttonClick(final ClickEvent event) { 
     log.info("click on button"); 
     EventBusFactory.getEventBusInstance().post(
      new FacetAddedEventImpl("click-" 
       + new SimpleDateFormat("HH:mm:ss").format(new Date()))); 
     log.info(mainController); 
     } 
    })); 
    } 
} 

MainController 클래스 :

class MainController { 
    private static final Logger log = Logger.getLogger(MainController.class); 

    public MainController() { 
    log.info("creating [email protected]" + Integer.toHexString(hashCode())); 
    EventBusFactory.getEventBusInstance().register(this); 
    } 

    @Subscribe 
    public void addFacetEvent(final FacetAddedEvent event) { 
    final String signature = "[email protected]" + Integer.toHexString(hashCode()) + ": "; 
    log.info("addFacetEvent in " + signature + event); 
    // getTreeTableViewBuilder returns extended ArrayList with fancy add 
    getTreeTableViewBuilder().addFacetToList(signature + event.getData()); 
    } 

    // plus other stuff like toString etc. 
} 

다음과 같은 작업을 수행 할 때 :

  1. 브라우저 (app # 1)에서 vaadin 앱을 시작하십시오.
  2. App1 # 버튼을 클릭하십시오.
  3. 다른 앱을 시작합니다 (App # 2).
  4. App2 # 단추를 클릭하십시오.
  5. App # 1의 탭으로 돌아갑니다.
  6. App1 # 버튼을 클릭하십시오.

    시작 SandpitApplication의 @의 75a5555a 버튼을 2e98f864
    클릭 // # @ MainController를 만드는
    1
    2e98f864 @ MC에서 addFacetEvent : FacetAddedEventImpl @ 6b527dc6

당신은 다음과 같은 결과를 얻을 수 있습니다 {데이터 : 클릭 13 : 42 : 45}
MainController @ 2e98f864 treeTableViewBuilder {[2e98f864 @ MC : 클릭 13 : 42 : 45]}
시작 SandpitApplication
3f9e529 @을 생성 MainController @ 버튼
클릭 // # 2e98f864 @ MC 2
addFacetEvent 2f8d604f : FacetAddedEventImpl 36c1fc67 @ {데이터 : 클릭 13 : 42 : 47} MC @ 2f8d604f에
addFacetEvent : 36c1fc67 {데이터 @ FacetAddedEventImpl : 클릭 - 13 : 42 : 47}
MainController @ 2f8d604f {treeTableViewBuilder : MC @ 2f8d604f : 클릭 13 : 42 : 47]} 버튼
클릭 // 1
2e98f864 @ MC에 addFacetEvent : FacetAddedEventImpl @ 42d32028 {data : click-13 : 42 : 49}
MC @ 2f8d604f의 addFacetEvent : FacetAddedEventImpl @ 42d32028 {data : click-13 : 42 : 49}
M ainController @ 2e98f864 {treeTableViewBuilder [2e98f864 @ MC : 클릭 13 : 42 : 45, MC @ 2e98f864 : 클릭 13 : 42 : 47, MC 2e98f864 @ 클릭 13 : 42 : 49]}

을 이제는 EventBus이라는 단일 응용 프로그램이 두 개의 응용 프로그램 전체 MainController 빈을 관리하며 각 응용 프로그램이 수신 이벤트임을 알 수 있습니다 (글로벌 EventBus로 해결 되었기 때문에). PS 정보

<bean id="eventBus" class="com.google.common.eventbus.EventBus" 
    scope="vaadinApplication" /> 

: 우리는 우리의 angel이라는 프로젝트에서 표준 구아바를 사용

당신이, 당신이 응용 프로그램 전체 이벤트 버스 콩을 만들 필요가 있다고 말하고 싶지만 달성하고자 할 것을 추측 시도 광범위하게 GWT ​​버전 필요 없음.

+0

답장을 보내 주셔서 감사합니다. – Spring