歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Spring事件通知機制詳解

Spring事件通知機制詳解

日期:2017/3/1 9:18:20   编辑:Linux編程

優勢

  • 解耦
  • 對同一種事件有多種處理方式
  • 不干擾主線(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