SpringBootアプリケーションEventPublisherの発行とアプリケーションEventイベントのリスニング

10551 ワード

資料アドレスSpring@Aync
実装方法
  • パブリッシュする必要があるイベントクラスをカスタマイズするには、ApplicationEventクラスまたはPayloadApplicationEvent(このクラスはApplicationEventの階層のみをカプセル化する)
  • を継承する必要がある.
  • は、@EventListenerを使用してイベント
  • を傍受する.
  • は、ApplicationEventPublisherを使用してカスタムイベント(@Autowired注入でよい)
  • を発行する.
    /**
     *        
     * @author peter
     * 2019/1/27 14:59
     */
    public class PersonSaveEvent<DATA> extends ApplicationEvent {
        private DATA data;
    
        public PersonSaveEvent(DATA source) {
            super(source);
            this.data = source;
        }
    
        public DATA getData() {
            return data;
        }
    }
    
    //    
    public void savePerson(Person person){
       personDao.save(person);
       publisher.publishEvent(new PersonSaveEvent<>(1));
    }
    //    
    @EventListener
    public void listenEvent(PersonSaveEvent<Integer> event) {
          System.out.println("   PersonSaveEvent  ;      :" + event.getData() + ";      " + Instant.ofEpochMilli(event.getTimestamp()));
    }
    

    メリット
    コアビジネスとサブビジネスをデカップリングし、後期のビジネスの拡張を容易にすることができます.新規ユーザ登録後にクーポンを発行する必要がある場合、ユーザを保存した後に、新規ユーザの を発行し、このイベントを傍受することによってクーポンを発行する機能を実現することができる.後期に新しいユーザーに対してxxx機能が追加され、 のリスナーを新たに作成して、以前の登録ロジックを変更する必要がなく、新しいビジネスロジックを処理することができます.
    注意事項
    1、         try-catch  ,         (    )       
    2、    @Order               ,@Order      ,      
    3、      s       try-catch runtime  ,    @TransactionalEventListener  
    

    @TransactionalEventListenerリスナー
    注記のソースコード:
     * <p>If the event is not published within the boundaries of a managed transaction, the
     * event is discarded unless the {@link #fallbackExecution} flag is explicitly set. If a
     * transaction is running, the event is processed according to its {@code TransactionPhase}.
    

    イベントのパブリケーションがトランザクション(@Transactional)の範囲内でない場合、fallbackExecutionフラグがtrueに設定されていない限り、イベントは傍受されません(@TransactionalEventListener(fallbackExecution = true)).トランザクションでは、トランザクションのどのフェーズでイベントをリスニングするかを選択できます.デフォルトでは、トランザクションのコミット後にリスニングされます.
             :@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
    

    Listenerでトランザクションを再開
    	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
        public void listenEvent1(PersonSaveEvent<Integer> event) {
            divide(event);
        }
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void divide(PersonSaveEvent<Integer> event) {
            System.out.println("   PersonSaveEvent  ;      :" + event.getData() + ";      " + Instant.ofEpochMilli(event.getTimestamp()));
        }
    

    以上のイベントはすべて同期であり、非同期が必要な場合は非同期サポートをオンにする必要があり、リスナーメソッドに@Async注釈を加えるとよい.
    /**
     *       
     * @author peter
     * @version 1.0
     * @date 2019/04/18 08:47
     */
    @Configuration
    @EnableAsync
    public class AsyncEventConfiguration implements AsyncConfigurer {
        @Override
        public Executor getAsyncExecutor() {
            return Executors.newCachedThreadPool();
        }
    }
    

    非同期実行が開始されると、メソッドの異常は投げ出されず、メソッド内部でのみ処理できます.方法外で異常を処理する必要がある場合:Async異常処理は文章の最後に