Spring事件機制
阿新 • • 發佈:2019-01-26
Java提供了事件機制,在使用spring的時候,我們可以把普通的java事件操作定義為bean整合到bean容器中,但還有一種更方便的方式,即使用spring已整合的事件支援。
在使用Spring的事件支援時,我們需要關注以下幾個物件:
1. ApplicationEvent:繼承自EventObject,同時是spring的application中事件的父類,需要被自定義的事件繼承。
2. ApplicationListener:繼承自EventListener,spring的application中的監聽器必須實現的介面,需要被自定義的監聽器實現其onApplicationEvent方法
3. ApplicationEventPublisherAware:在spring的context中希望能釋出事件的類必須實現的介面,該介面中定義了設定ApplicationEventPublisher的方法,由ApplicationContext呼叫並設定。在自己實現的ApplicationEventPublisherAware子類中,需要有ApplicationEventPublisher屬性的定義。
4. ApplicationEventPublisher:spring的事件釋出者介面,定義了釋出事件的介面方法publishEvent。因為ApplicationContext實現了該介面,因此spring的ApplicationContext例項具有釋出事件的功能(publishEvent方法在AbstractApplicationContext中有實現)。在使用的時候,只需要把ApplicationEventPublisher的引用定義到ApplicationEventPublisherAware的實現中,spring容器會完成對ApplicationEventPublisher的注入。
在spring的bean配置中,因為事件是由事件源發出的,不需要註冊為bean由spring容器管理。所以在spring的配置中,只需配置自定義的ApplicationEventListener和publisherAware(即實現了ApplicationEventPublisherAware介面的釋出類),而對於ApplicationEventPublisher的管理和注入都由容器來完成。
基於spring的事件簡單實現如下:
1. 定義ApplicationEvent
Java程式碼
2. 定義ApplicationEventListener
Java程式碼
3. 定義ApplicationEventPublisherAware
Java程式碼
4. 定義bean配置
Java程式碼
5. 使用事件
Java程式碼
從實現來上,和使用基本的java事件流程大體一致,不同的是這裡不需要自定義釋出者,而使用spring實現提供的事件釋出實現。當然,這裡卻引入了ApplicationEventPublisherAware。
在使用Spring的事件支援時,我們需要關注以下幾個物件:
1. ApplicationEvent:繼承自EventObject,同時是spring的application中事件的父類,需要被自定義的事件繼承。
2. ApplicationListener:繼承自EventListener,spring的application中的監聽器必須實現的介面,需要被自定義的監聽器實現其onApplicationEvent方法
3. ApplicationEventPublisherAware:在spring的context中希望能釋出事件的類必須實現的介面,該介面中定義了設定ApplicationEventPublisher的方法,由ApplicationContext呼叫並設定。在自己實現的ApplicationEventPublisherAware子類中,需要有ApplicationEventPublisher屬性的定義。
4. ApplicationEventPublisher:spring的事件釋出者介面,定義了釋出事件的介面方法publishEvent。因為ApplicationContext實現了該介面,因此spring的ApplicationContext例項具有釋出事件的功能(publishEvent方法在AbstractApplicationContext中有實現)。在使用的時候,只需要把ApplicationEventPublisher的引用定義到ApplicationEventPublisherAware的實現中,spring容器會完成對ApplicationEventPublisher的注入。
在spring的bean配置中,因為事件是由事件源發出的,不需要註冊為bean由spring容器管理。所以在spring的配置中,只需配置自定義的ApplicationEventListener和publisherAware(即實現了ApplicationEventPublisherAware介面的釋出類),而對於ApplicationEventPublisher的管理和注入都由容器來完成。
基於spring的事件簡單實現如下:
1. 定義ApplicationEvent
Java程式碼
- package com.nuc.event;
- import org.springframework.context.ApplicationEvent;
- /**
- * 定義Spring容器中的事件,與java普通的事件定義相比,只是繼承的父類不同而已,在
- * 在定義上並未有太大的區別,畢竟ApplicationEvent也是繼承自EventObject的。
- */
- public class MethodExecutionEvent extends ApplicationEvent {
- private static final long serialVersionUID = 2565706247851725694L;
- private String methodName;
- private MethodExecutionStatus methodExecutionStatus;
- public MethodExecutionEvent(Object source) {
- super(source);
- }
- public MethodExecutionEvent(Object source, String methodName, MethodExecutionStatus methodExecutionStatus) {
- super
- this.methodName = methodName;
- this.methodExecutionStatus = methodExecutionStatus;
- }
- public String getMethodName() {
- return methodName;
- }
- public void setMethodName(String methodName) {
- this.methodName = methodName;
- }
- public MethodExecutionStatus getMethodExecutionStatus() {
- return methodExecutionStatus;
- }
- public void setMethodExecutionStatus(MethodExecutionStatus methodExecutionStatus) {
- this.methodExecutionStatus = methodExecutionStatus;
- }
- }
package com.nuc.event;
import org.springframework.context.ApplicationEvent;
/**
* 定義Spring容器中的事件,與java普通的事件定義相比,只是繼承的父類不同而已,在
* 在定義上並未有太大的區別,畢竟ApplicationEvent也是繼承自EventObject的。
*/
public class MethodExecutionEvent extends ApplicationEvent {
private static final long serialVersionUID = 2565706247851725694L;
private String methodName;
private MethodExecutionStatus methodExecutionStatus;
public MethodExecutionEvent(Object source) {
super(source);
}
public MethodExecutionEvent(Object source, String methodName, MethodExecutionStatus methodExecutionStatus) {
super(source);
this.methodName = methodName;
this.methodExecutionStatus = methodExecutionStatus;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public MethodExecutionStatus getMethodExecutionStatus() {
return methodExecutionStatus;
}
public void setMethodExecutionStatus(MethodExecutionStatus methodExecutionStatus) {
this.methodExecutionStatus = methodExecutionStatus;
}
}
2. 定義ApplicationEventListener
Java程式碼
- package com.nuc.listener;
- import org.springframework.context.ApplicationEvent;
- import org.springframework.context.ApplicationListener;
- import com.nuc.event.MethodExecutionEvent;
- import com.nuc.event.MethodExecutionStatus;
- /**
- * Spring容器中的事件監聽器,與java中基本的事件監聽器的定義相比,這裡需要實現ApplicationListener介面
- * ApplicationListener介面雖然繼承自EventListener,但擴充套件了EventListener
- * 它在介面宣告中定義了onApplicationEvent的介面方法,而不像EventListener只作為標記性介面。
- */
- public class MethodExecutionEventListener implements ApplicationListener {
- public void onApplicationEvent(ApplicationEvent event) {
- if (event instanceof MethodExecutionEvent) {
- if (MethodExecutionStatus.BEGIN
- .equals(((MethodExecutionEvent) event)
- .getMethodExecutionStatus())) {
- System.out.println("It's beginning");
- }
- if (MethodExecutionStatus.END.equals(((MethodExecutionEvent) event).getMethodExecutionStatus())) {
- System.out.println("It's ending");
- }
- }
- }
- }
package com.nuc.listener;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import com.nuc.event.MethodExecutionEvent;
import com.nuc.event.MethodExecutionStatus;
/**
* Spring容器中的事件監聽器,與java中基本的事件監聽器的定義相比,這裡需要實現ApplicationListener介面
* ApplicationListener介面雖然繼承自EventListener,但擴充套件了EventListener
* 它在介面宣告中定義了onApplicationEvent的介面方法,而不像EventListener只作為標記性介面。
*/
public class MethodExecutionEventListener implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof MethodExecutionEvent) {
if (MethodExecutionStatus.BEGIN
.equals(((MethodExecutionEvent) event)
.getMethodExecutionStatus())) {
System.out.println("It's beginning");
}
if (MethodExecutionStatus.END.equals(((MethodExecutionEvent) event).getMethodExecutionStatus())) {
System.out.println("It's ending");
}
}
}
}
3. 定義ApplicationEventPublisherAware
Java程式碼
- package com.nuc.publisher;
- import org.springframework.context.ApplicationEventPublisher;
- import org.springframework.context.ApplicationEventPublisherAware;
- import com.nuc.event.MethodExecutionEvent;
- import com.nuc.event.MethodExecutionStatus;
- public class MethodExecutionEventPublisher implements
- ApplicationEventPublisherAware {
- private ApplicationEventPublisher eventPublisher;
- public void methodToMonitor() {
- MethodExecutionEvent beginEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.BEGIN);
- this.eventPublisher.publishEvent(beginEvent);
- //TODO
- MethodExecutionEvent endEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.END);
- this.eventPublisher.publishEvent(endEvent);
- }
- public void setApplicationEventPublisher(
- ApplicationEventPublisher applicationEventPublisher) {
- this.eventPublisher = applicationEventPublisher;
- }
- }
package com.nuc.publisher;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import com.nuc.event.MethodExecutionEvent;
import com.nuc.event.MethodExecutionStatus;
public class MethodExecutionEventPublisher implements
ApplicationEventPublisherAware {
private ApplicationEventPublisher eventPublisher;
public void methodToMonitor() {
MethodExecutionEvent beginEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.BEGIN);
this.eventPublisher.publishEvent(beginEvent);
//TODO
MethodExecutionEvent endEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.END);
this.eventPublisher.publishEvent(endEvent);
}
public void setApplicationEventPublisher(
ApplicationEventPublisher applicationEventPublisher) {
this.eventPublisher = applicationEventPublisher;
}
}
4. 定義bean配置
Java程式碼
- <?xml version="1.0" encoding="GBK"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
- default-autowire="byName">
- <bean id="methodExecListener" class="com.nuc.listener.MethodExecutionEventListener"></bean>
- <bean id="evtPublisher" class="com.nuc.publisher.MethodExecutionEventPublisher"></bean>
- </beans>
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-autowire="byName">
<bean id="methodExecListener" class="com.nuc.listener.MethodExecutionEventListener"></bean>
<bean id="evtPublisher" class="com.nuc.publisher.MethodExecutionEventPublisher"></bean>
</beans>
5. 使用事件
Java程式碼
- package com.nuc;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.nuc.publisher.MethodExecutionEventPublisher;
- public class App
- {
- public static void main( String[] args )
- {
- ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
- MethodExecutionEventPublisher publisher = (MethodExecutionEventPublisher)context.getBean("evtPublisher");
- publisher.methodToMonitor();
- }
- }
package com.nuc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.nuc.publisher.MethodExecutionEventPublisher;
public class App
{
public static void main( String[] args )
{
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MethodExecutionEventPublisher publisher = (MethodExecutionEventPublisher)context.getBean("evtPublisher");
publisher.methodToMonitor();
}
}
從實現來上,和使用基本的java事件流程大體一致,不同的是這裡不需要自定義釋出者,而使用spring實現提供的事件釋出實現。當然,這裡卻引入了ApplicationEventPublisherAware。