IoC容器(5):アプリケーションEventPublisher


10. ApplicationEventPublisher


イベントプログラミングに必要なインタフェースを提供します.ファイバモードインプリメンテーション.
ApplicationContext extends ApplicationEventPublisher
  • publishEvent(ApplicationEvent event)
  • イベントの作成
  • アプリケーションイベント継承
  • スプリング4.2から、クラスを継承する必要がなく、アクティブに使用できます.
  • public class MyEvent extends ApplicationEvent {
    
        private int data;
        
        public MyEvent(Object source) {
            super(source);
        }
        
         public MyEvent(Object source, int data) {
            this.source = source;
            this.data = data;
        }
        
         public int getData(){
            return data;
        }
    }
    ApplicationContextには、このイベントをトリガーする機能があります.
    イベントを起動する方法
  • ApplicationEventPublisher.publishEvent();
  • @Component
    public class AppRunner implements ApplicationRunner {
    
        /*
        @Autowired
        ApplicationContext applicationContext;
        */
    
        @Autowired
        ApplicationEventPublisher publishEvent;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            publishEvent.publishEvent(new MyEvent(this, 100));
        }
    }
    このイベントを処理するにはイベントハンドラが必要ですが、イベントハンドラは空に登録する必要があります.
    イベントの処理方法
  • ApplicationListener<イベント>インプリメンテーションのクラスを作成し、空に登録します.
  • スプリング4.2から、@EventListenerを使用して空の方法を使用できます.
  • は基本的にsynchronizedです.
  • の順序を決めたい場合は、@Orderと一緒に使用してください.
  • を非同期で実行する場合は、@Asyncとともに使用します.
  • ApplicationListener<イベント>インプリメンテーションのクラスを作成し、空に登録します.
  • @Component
    public class MyEventHandler implements ApplicationListener<MyEvent> {
    
        @Override
        public void onApplicationEvent(MyEvent myEvent) {
            System.out.println("이벤트 받았다. 데이터는 " + myEvent.getData());
        }
    }
  • スプリング4.2から、@EventListenerを使用して空の方法を使用できます.
  • 励起イベントのソースの確認
    public class MyEvent {
    
        private int data;
    
        private Object source;
    
        public MyEvent(Object source, int data) {
            this.source = source;
            this.data = data;
        }
    
        public Object getSource(){
            return source;
        }
    
        public int getData(){
            return data;
        }
    }
    @Component
    public class MyEventHandler {
    
        @EventListener
        public void handle(MyEvent event){
            System.out.println("이벤트 받았다. 데이터는 " + event.getData());
        }
    EventHandlerにはいろいろな種類があると仮定します
    @Component
    public class MyEventHandler {
    
        @EventListener
        public void handle(MyEvent event){
            System.out.println(Thread.currentThread().toString());
            System.out.println("이벤트 받았다. 데이터는 " + event.getData());
        }
    @Component
    public class AnotherHandler {
    
        @EventListener
        public void handler(MyEvent myEvent){
            System.out.println(Thread.currentThread().toString());
            System.out.println("Another " + myEvent.getData());
        }
    }
    では、この2つのハンドルが実行されます.デフォルトでは順番に実行されます(synchronized).これを確認するには、スレッドの名前を印刷するだけで、両方ともメインスレッドで実行します.
  • の順序を決めたい場合は、@Orderと一緒に使用してください.
  • 順番に実行する場合は、シーケンスを指定できます.
    @Component
    public class AnotherHandler {
    
        @EventListener
        @Order(Ordered.HIGHEST_PRECEDENCE + 2)
        public void handler(MyEvent myEvent){
            System.out.println(Thread.currentThread().toString());
            System.out.println("Another " + myEvent.getData());
        }
    }
    @Component
    public class MyEventHandler {
    	
        @EventListener
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public void handle(MyEvent event){
            System.out.println(Thread.currentThread().toString());
            System.out.println("이벤트 받았다. 데이터는 " + event.getData());
        }
  • を非同期で実行する場合は、@Asyncとともに使用します.
  • 順序が悪い.スレッドプールごとに個別に実行
    @SpringBootApplication
    @EnableAsync
    public class Springtest6Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Springtest6Application.class, args);
        }
    }
    @Component
    public class AnotherHandler {
    
        @EventListener
        @Async
        public void handler(MyEvent myEvent){
            System.out.println(Thread.currentThread().toString());
            System.out.println("Another " + myEvent.getData());
        }
    }
    @Component
    public class MyEventHandler {
    	
        @EventListener
        @@Async
        public void handle(MyEvent event){
            System.out.println(Thread.currentThread().toString());
            System.out.println("이벤트 받았다. 데이터는 " + event.getData());
        }
    スプリングが提供する基本イベント(ApplicationContext)に関連
  • ContextRefreshedEvent:ApplicationContextの初期化またはリフレッシュ時に発生します.
  • ContextStartedEvent:ApplicationContext start()は、ライフサイクル中に起動信号を受信したときに発生します.
  • ContextStoppedEvent:ApplicationContext停止()は、ライフサイクル中に停止信号を受信したときに発生します.
  • ContextClosedEvent:ApplicationContextがオフ()になり、モノクロ調空が消失したときに発生します.
  • RequestHandledEvent:HTTPリクエストの処理中に発生します.
  • @Component
    public class MyEventHandler {
    
        @EventListener
        @Async
        public void handle(MyEvent event){
            System.out.println(Thread.currentThread().toString());
            System.out.println("이벤트 받았다. 데이터는 " + event.getData());
        }
        
       @EventListener
        @Async
        public void handle(ContextRefreshedEvent event){
            System.out.println(Thread.currentThread().toString());
            System.out.println("ContextRefreshedEvent");
            //var applicationContext = event.getApplicationContext()
        }
         
        @EventListener
        @Async
        public void handle(ContextClosedEvent event){
            System.out.println(Thread.currentThread().toString());
            System.out.println("ContextClosedEvent");
            //var applicationContext = event.getApplicationContext()
        }
    }
    リファレンス
  • インフラストラクチャ:スプリングフレームキーテクノロジー(白旗線)