Spring中的事件監聽機制在專案中的應用
最經在做專案的時候,呼叫某個介面的時候為了呼叫地圖,而不希望因為呼叫超時影響到主執行緒,使用了spring的時間監聽機制。
Spring中提供一些Aware相關的介面,BeanFactoryAware、 ApplicationContextAware、ResourceLoaderAware、ServletContextAware等等,其中最常用到的是ApplicationContextAware。實現ApplicationContextAware的Bean,在Bean被初始後,將會被注入ApplicationContext的例項。ApplicationContextAware提供了publishEvent()方法,實現Observer(觀察者)設計模式的事件傳播機,提供了針對Bean的事件傳播功能。通過Application.publishEvent方法,我們可以將事件通知系統內所有的ApplicationListener。
Spring事件處理一般過程:
◆定義Event類,繼承org.springframework.context.ApplicationEvent。
◆編寫釋出事件類Publisher,實現org.springframework.context.ApplicationContextAware介面。
◆覆蓋方法setApplicationContext(ApplicationContext applicationContext)和釋出方法publish(Object obj)。
◆定義時間監聽類EventListener,實現ApplicationListener介面,實現方法onApplicationEvent(ApplicationEvent event)。
專案中的虛擬碼
- 定義Event類,繼承org.springframework.context.ApplicationEvent。
public class Gis0002SuccessEvent extends ApplicationEvent
{
/**
* <B>Summary:</B> <Br>
* serialVersionUID:TODO(用一句話描述這個變量表示什麼) <Br>
*
* @since Ver @version
*/
private static final long serialVersionUID = 1L;
public Gis0002SuccessEvent ( GiS0002 source )
{
super ( source );
}
}
2.編寫釋出事件類Publisher,實現org.springframework.context.ApplicationContextAware介面。
3.覆蓋方法setApplicationContext(ApplicationContext applicationContext)和釋出方法publish(Object obj)。
public class AgA01003ServiceImpl implements AgA01003Service,ApplicationContextAware{
//把救援人的資訊傳給地圖 2015.07.21
public void dealMapMoniter(AgA01003Entity aga01003Entity){
GiS0002 giS0002 = new GiS0002();
log.info("--救援監控救援人資訊資料---"+JsonUtil.toJSONString ( aga01003Entity ));
/******************以下是處理工單服務人員資訊資料 begin*****************************/
giS0002.setTicketID ( aga01003Entity.getTicketID ( ) );//工單編號
giS0002.setRescueName ( aga01003Entity.getRescueName ( ) );//救援人員名稱
giS0002.setRescuePhone ( aga01003Entity.getRescuePhone ( ) );//救援人員電話
//giS0002.setRealServiceType( aga01003Entity.getServiceCode ( ) );//服務專案程式碼
//設定服務中文名稱 edit by zhaolei 2015-08-03
String serviceName = sendMessageService.getSpTypeMateDataNameByCode(aga01003Entity.getServiceCode ( ));
giS0002.setRealServiceType( serviceName );//服務專案程式碼
giS0002.setRescueLatitude ( aga01003Entity.getCaseLatitude ( ) );
giS0002.setRescueLongitude ( aga01003Entity.getCaseLongitude ( ) );
giS0002.setRescueVehicleNo ( aga01003Entity.getRescueVehicleNo ( ) );//車牌號
//因呼叫地圖時,如超時,會影響到主流程,所以改為監聽 2015.08.10
this.ac.publishEvent ( new Gis0002SuccessEvent ( giS0002 ) );
}
}
定義時間監聽類EventListener,實現ApplicationListener介面,實現方法onApplicationEvent(ApplicationEvent event)。
public class Gis0002Listener implements SmartApplicationListener
{
Logger log = LoggerFactory.getLogger ( Gis0002Listener.class );
@Resource( name = "dictionaryService" )
private DictionaryService dictionaryService;
@Resource(name="logManagerSerivce")
private LogManagerSerivceImpl logManageService;
@Override
@Async //配置成非同步處理資料
public void onApplicationEvent ( ApplicationEvent arg0 )
{
GiS0002 giS0002 = (GiS0002)arg0.getSource ( );
Enum enums = dictionaryService.searchByCode ( InitSpring.getMessage ( "RUNTIMEENUM" ) ,
"monitorRescue" );
//從配置庫中取得介面url
String urlName = enums.getName ( );
log.info("救援監控救援人資訊介面="+urlName);
JacksonJsonSimpleMarshaller sm = new JacksonJsonSimpleMarshaller ( );
String resJson = sm.marshaller ( giS0002 ,new ByteArrayOutputStream ( ) );
log.info("救援監控救援人資訊請求引數="+resJson);
List<NameValuePair> json = new ArrayList<NameValuePair> ( );
json.add ( new BasicNameValuePair ( "RequestBodyJson" , resJson ) );
try
{
//呼叫救援緘口地圖
String returnData = HttpUtils.httpPost (urlName , json );
log.info("救援監控救援人資訊介面返回="+JsonUtil.toJSONString ( returnData ));
if( returnData.matches ( ".*404.*" ) ){
logManageService.saveLog ( giS0002 , returnData ,"" ,
"", giS0002.getTicketID ( ) ,
"1" , Contants.GiS0002 );
}
}
catch ( HttpHostConnectException e )
{
log.error ( e.getMessage ( ) );
logManageService.saveLog ( giS0002 , "" ,e.getMessage ( ) ,
"", giS0002.getTicketID ( ) ,
"1" , Contants.GiS0002 );
}
}
@Override
public int getOrder ( )
{
return 1;
}
@Override
public boolean supportsEventType ( Class<? extends ApplicationEvent> eventType )
{
return eventType == Gis0002SuccessEvent.class;
}
@Override
public boolean supportsSourceType ( Class<?> sourceType )
{
return sourceType ==GiS0002.class;
}
}