복붙노트

[SPRING] Spring ApplicationListener가 2 개 이상의 이벤트 유형을 수신 할 수있게 할 수 있습니까?

SPRING

Spring ApplicationListener가 2 개 이상의 이벤트 유형을 수신 할 수있게 할 수 있습니까?

내 수업을 듣고 그에 따라 (그리고 다르게) 처리 할 수있는 두 가지 유형의 이벤트가 있습니다.

나는 시도했다 : 공용 클래스 ListenerClass는 ApplicationListener , ApplicationListener

이것은 나에게 다른 인자로 같은 인터페이스를 두 번 구현할 수 없다는 오류를 준다.

ApplicationEvent (또는 Foo와 Bar가 구현할 다른 공용 인터페이스)에 대한 리스너를 구현하지 않고 instanceof를 사용하여 어떤 경로를 취할지 결정할 때 다른 옵션이 있습니까?

감사!

해결법

  1. ==============================

    1.이 답변의 끝 부분에서 Spring 4.2 업데이트를 참조하십시오!

    이 답변의 끝 부분에서 Spring 4.2 업데이트를 참조하십시오!

    봄 <4.2

    정말로.

    인수 (예 : ApplicationEvent) 나 Foo와 Bar가 구현하는 공용 인터페이스에 대해 공통의 수퍼 클래스를 사용할 수 있습니다.

    public class ListenerClass implements ApplicationListener<ApplicationEvent> {
        ...
        if(event instanceOf Foo || event instance of Bar) {
        }
    }
    

    다른 방법은 두 개의 응용 프로그램 수신기를 사용하는 것입니다.

    public class ListenerClass {
    
        void onFoo(Foo foo){}
        void onBar(Bar bar){}
    
        static class FooListener implements ApplicationListener<Foo> {
           ListenerClass listerner;
           ....
           public void onApplicationEvent(Foo foo) {
               listener.onFoo(foo);
           }
        }
        static class BarListener implements ApplicationListener<Bar> {
           ListenerClass listerner;
           ....
           public void onApplicationEvent(Bar bar) {
               listener.onBar(bar);
           }
        }
    }
    

    중요 : 3 개의 모든 인스턴스는 스프링 빈이어야합니다!

    물론 이러한 기능을 직접 구현할 수도 있습니다. 적어도 두 가지 선택 사항이 있습니다. 스프링 이벤트 디스패처 프레임 워크를 기반으로하거나 완전히 분리되어 있습니다. 두 번째 선택의 경우 CDI 이벤트 메카니즘 (CDI-Event Mechanim)을 살펴보고 일부 스프링 포트를 검색 할 수 있습니다.

    나는 내 자신으로 몇 년 먼저 (2007/2008에서 추측) 첫 번째 선택을 구현했습니다. 모든 이벤트를 청취하는 이벤트 디스패처를 맡고 있습니다. 그것은 XML 파일을 통해 구성되었습니다. 이 XML 파일에는 "참조"가 들어 있습니다! 디스패치되어야하는 모든 이벤트에 대한 빈의 메소드에 -이 메소드는 리플렉션에 의해 호출되었을 것이다. 그래서 강력한 접근 형 처리기 메소드 (이 접근법의 목표 였음)를 가질 수 있었고 하나의 클래스에서 여러 핸들러 메소드를 가질 수도있었습니다. 요즘에는 xml 파일을 건너 뛰고 Annotations와 Bean-Post-Processor를 사용할 것입니다.

    Spring 4.2 업데이트

    Spring 4.2는 두 개의 다른 이벤트 리스너 메소드를 하나의 bean에 둘 수있는 향상된 이벤트 리스너 구성 (주석에 기반)을 갖습니다.

    @Component
    public class ListenerClass {
    
      @EventListener
      public void handleFooEvent(Foo fooEvent) {...}
    
      @EventListener
      public void handleBarEvent(Bar barEvent) {...}
    
    }
    
  2. ==============================

    2.봄 <4.2

    봄 <4.2

    instanceof 또는 정적 클래스보다 조금 더 우아한 것은 방문자 패턴입니다. 방문자 패턴은 이전 Spring의 단점에 대한 매우 유용한 대안이라고 생각합니다.

    public class ListenerClass implements ApplicationListener<FooBarBase>, FooBarVisitor {
        @Override
        public void onApplicationEvent(FooBarBase fooBarBase) {
            fooBarBase.accept(this);
        }
    
        @Override
        public void visitFoo(Foo foo) {
            System.out.println("Handling Foo Event...");
        }
    
        @Override
        public void visitBar(Bar bar) {
            System.out.println("Handling Bar Event...");
        }
    }
    
    public interface FooBarVisitor {
        void visitFoo(Foo foo);
        void visitBar(Bar bar);
    }
    
    public abstract class FooBarBase extends ApplicationEvent {
        public FooBarBase(Object source) {
            super(source);
        }
    
        abstract void accept(FooBarVisitor visitor);
    }
    
    public class Bar extends FooBarBase {
        public Bar(Object source) {
            super(source);
        }
    
        @Override
        void accept(FooBarVisitor visitor) {
            visitor.visitBar(this);
        }
    }
    
    public class Foo extends FooBarBase {
        public Foo(Object source) {
            super(source);
        }
    
        @Override
        void accept(FooBarVisitor visitor) {
            visitor.visitFoo(this);
        }
    }
    
  3. from https://stackoverflow.com/questions/8836073/is-it-possible-to-make-a-spring-applicationlistener-listen-for-2-or-more-types-o by cc-by-sa and MIT license