歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Spring事件通知機制詳解

優勢

  • 解耦
  • 對同一種事件有多種處理方式
  • 不干擾主線(main line)

起源

要講spring的事件通知機制,就要先了解一下spring中的這些接口和抽象類:

  • ApplicationEventPublisherAware        接口:用來 publish event
  • ApplicationEvent                  抽象類,記錄了source和初始化時間戳:用來定義Event
  • ApplicationListener<E extends ApplicationEvent>  :用來監聽事件

構建自己的事件機制案例

測試案例

測試入口

package com.meituan.spring.testcase.listener;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.concurrent.TimeUnit;

/**
 * Created by zhangxiaoguang on 16/1/27 下午11:40.
 * -----------------------------
 * Desc:
 */
public class TestPortal {
  public static void main(String[] args) throws InterruptedException {

      final ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");

      String[] definitionNames = applicationContext.getBeanDefinitionNames();
      System.out.println("==============bean====start=================");
      for (String definitionName : definitionNames) {
        System.out.println("bean----:" + definitionName);
      }
      System.out.println("==============bean====end=================");
      System.out.println();
      final CustomizePublisher customizePublisher = applicationContext.getBean(CustomizePublisher.class);


      Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
              System.out.println("開始吃飯:");

              MealEvent lunchEvent = new MealEvent("A吃午飯了", MealEnum.lunch);
              MealEvent breakfastEvent = new MealEvent("B吃早飯了", MealEnum.breakfast);
              MealEvent dinnerEvent = new MealEvent("C吃晚飯了", MealEnum.dinner);
              customizePublisher.publish(lunchEvent);
              TimeUnit.SECONDS.sleep(1l);
              customizePublisher.publish(breakfastEvent);
              TimeUnit.SECONDS.sleep(1l);
              customizePublisher.publish(dinnerEvent);
              TimeUnit.SECONDS.sleep(1l);

              System.out.println("他們吃完了!");
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
        }
      });
      thread.setName("meal-thread");
      thread.start();

      System.out.println(Thread.currentThread().getName() + " is waiting for ....");
      thread.join();
      System.out.println("Done!!!!!!!!!!!!");
  }
}

TestPortal

測試結果

測試成員

  • MealListener :MealEvent                  演員
  • TroubleListener :TroubleEvent         演員
  • AllAcceptedListener                            演員
  • MealEnum                                          道具
  • TestPortal                                           入口
  • CustomizePublisher                           導演

成員代碼

接受全部事件的演員(很負責任啊)

package com.meituan.spring.testcase.listener;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * Created by zhangxiaoguang on 16/1/27 下午11:27.
 * -----------------------------
 * Desc:
 */
@Component
public class AllAcceptedListener implements ApplicationListener<ApplicationEvent> {
  @Override
  public void onApplicationEvent(ApplicationEvent event) {
      System.out.println(">>>>>>>>>>>>>>>>event:" + event);
  }
}

AllAcceptedListener

導演負責分發事件

package com.meituan.spring.testcase.listener;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

/**
 * Created by zhangxiaoguang on 16/1/28 上午1:41.
 * -----------------------------
 * Desc:
 */
@Component
public class CustomizePublisher implements ApplicationEventPublisherAware {

  private ApplicationEventPublisher applicationEventPublisher;

  public void publish(MealEvent event) {
      applicationEventPublisher.publishEvent(event);
  }

  @Override
  public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
      this.applicationEventPublisher = applicationEventPublisher;
  }
}

CustomizePublisher

負責處理吃飯事件的演員

package com.meituan.spring.testcase.listener;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * Created by zhangxiaoguang on 16/1/27 下午11:27.
 * -----------------------------
 * Desc:
 */
@Component
public class MealListener implements ApplicationListener<MealEvent> {
  @Override
  public void onApplicationEvent(MealEvent event) {
      System.out.println(String.format(">>>>>>>>>>>thread:%s,type:%s,event:%s",
            Thread.currentThread().getName(), event.getMealEnum(), event));

      dispatchEvent(event);
  }

  private void dispatchEvent(MealEvent event) {
      switch (event.getMealEnum()) {
        case breakfast:
            System.out.println(event.getMealEnum() + " to handle!!!");
            break;
        case lunch:
            System.out.println(event.getMealEnum() + " to handle!!!");
            break;
        case dinner:
            System.out.println(event.getMealEnum() + " to handle!!!");
            break;
        default:
            System.out.println(event.getMealEnum() + " error!!!");
            break;
      }
  }
}

MealListener

吃飯消息

package com.meituan.spring.testcase.listener;

import org.springframework.context.ApplicationEvent;

/**
 * Created by zhangxiaoguang on 16/1/27 下午11:24.
 * -----------------------------
 * Desc:吃飯事件
 */
public class MealEvent extends ApplicationEvent {

  private MealEnum mealEnum;

  /**
    * @param mealContent
    *        吃什麼
    * @param mealEnum
    *        早餐還是午餐?
    */
  public MealEvent(String mealContent, MealEnum mealEnum) {
      super(mealContent);
      this.mealEnum = mealEnum;
  }

  public MealEnum getMealEnum() {
      return mealEnum;
  }
}

MealEvent

工具

package com.meituan.spring.testcase.listener;

/**
 * Created by zhangxiaoguang on 16/1/27 下午11:29.
 * -----------------------------
 * Desc:
 */
public enum MealEnum {
  breakfast,
  lunch,
  dinner
}

MealEnum

令人厭煩的演員

package com.meituan.spring.testcase.listener;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * Created by zhangxiaoguang on 16/1/27 下午11:27.
 * -----------------------------
 * Desc:
 */
@Component
public class TroubleListener implements ApplicationListener<TroubleEvent> {
  @Override
  public void onApplicationEvent(TroubleEvent event) {
      System.out.println(">>>>>>>>>>>>>>>>event:" + event);
  }
}

TroubleListener

令人厭煩的事件

package com.meituan.spring.testcase.listener;

import org.springframework.context.ApplicationEvent;

/**
 * Created by zhangxiaoguang on 16/1/27 下午11:24.
 * -----------------------------
 * Desc:令人厭煩的事件
 */
public class TroubleEvent extends ApplicationEvent {
  public TroubleEvent(Object source) {
      super(source);
  }
}

TroubleEvent

總結

詳細定制 event 類型的,則相關定制的listener會處理對應的消息,其他listener不會管閒事;

制定頂級 event 類型的,ApplicationEvent的,則會處理所有的事件。

Spring中如何配置Hibernate事務 http://www.linuxidc.com/Linux/2013-12/93681.htm

Struts2整合Spring方法及原理 http://www.linuxidc.com/Linux/2013-12/93692.htm

基於 Spring 設計並實現 RESTful Web Services http://www.linuxidc.com/Linux/2013-10/91974.htm

Spring-3.2.4 + Quartz-2.2.0集成實例 http://www.linuxidc.com/Linux/2013-10/91524.htm

使用 Spring 進行單元測試 http://www.linuxidc.com/Linux/2013-09/89913.htm

運用Spring注解實現Netty服務器端UDP應用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm

Spring 3.x 企業應用開發實戰 PDF完整高清掃描版+源代碼 http://www.linuxidc.com/Linux/2013-10/91357.htm

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2016-03/129001p2.htm

Copyright © Linux教程網 All Rights Reserved