Spring 事件驅動模型包括三個概念:事件、事件監聽器、事件發佈者。bash
public abstract class ApplicationEvent extends EventObject {
private final long timestamp;
// protected transient Object source; 父類中定義
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
}
複製代碼
自定義事件時只須要繼承ApplicationEventapp
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
複製代碼
ApplicationListener 接口限定 ApplicationEvent的子類做爲接口中方法的參數,因此每個監聽器都是針對某一具體的事件進行監聽。異步
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event){
publishEvent((Object) event);
}
void publishEvent(Object event);
}
複製代碼
ApplicationContext 實現了ApplicationEventPublisher,因此發佈事件時可直接經過ApplicationContextide
可在監聽方法上使用@EventListener註解代替實現ApplicationListener接口, 並可在方法上添加@Order註解實現監聽器處理的順序ui
@TransactionalEventListener 可隔離事件發佈和監聽的事務this
@Data
public class HomeWorkEvent extends ApplicationEvent {
/**
* 做業內容
*/
private String content;
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public HomeWorkEvent(Object source, String content) {
super(source);
this.content = content;
}
}
/**
* 定義做業的監聽者學生
* @author xup
* @date 2019/12/28 21:57
*/
@Component
public class StudentListener implements ApplicationListener<HomeWorkEvent> {
@Override
public void onApplicationEvent(HomeWorkEvent event) {
System.out.println("StudentListener接收到老師佈置的做業:" + event.getContent());
}
}
/**
* 做業發佈者--教師
* @author xup
* @date 2019/12/28 21:59
*/
@Component
public class TeacherPublisher {
@Autowired
private ApplicationContext applicationContext;
public void publishHomeWork(String content){
HomeWorkEvent homeWorkEvent = new HomeWorkEvent(this, content);
applicationContext.publishEvent(homeWorkEvent);
}
}
/**
* 定義做業的監聽者學生
* @author xup
* @date 2019/12/28 21:57
*/
@Component
public class StudentListener2 {
@EventListener
@Order(2)
public void receiveHomeWork(HomeWorkEvent event) {
System.out.println("StudentListener2接收到老師佈置的做業2:" + event.getContent());
}
@EventListener(classes = {HomeWorkEvent.class})
@Order(1)
public void receiveHomeWork(Object event) {
System.out.println("StudentListener2接收到老師佈置的做業1:" + ((HomeWorkEvent)event).getContent());
}
}
@RunWith(value= SpringJUnit4ClassRunner.class)
@SpringBootTest
public class TeacherPublisherTest {
@Autowired
private TeacherPublisher teacherPublisher;
@Test
public void publish(){
teacherPublisher.publishHomeWork("背誦課文。。");
}
}
輸出
StudentListener2接收到老師佈置的做業1:背誦課文。。
StudentListener2接收到老師佈置的做業2:背誦課文。。
StudentListener接收到老師佈置的做業:背誦課文。。
複製代碼