Spring 事件驅動模型

Spring 事件驅動模型包括三個概念:事件、事件監聽器、事件發佈者。bash

事件 ApplicationEvent

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

事件監聽器 ApplicationListener

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

    void onApplicationEvent(E event);
}
複製代碼

ApplicationListener 接口限定 ApplicationEvent的子類做爲接口中方法的參數,因此每個監聽器都是針對某一具體的事件進行監聽。異步

事件發佈者 ApplicationEventPublisher

@FunctionalInterface
public interface ApplicationEventPublisher {

    default void publishEvent(ApplicationEvent event){
        publishEvent((Object) event);
    }

    void publishEvent(Object event);
}
複製代碼

ApplicationContext 實現了ApplicationEventPublisher,因此發佈事件時可直接經過ApplicationContextide

特色

  • 一個事件可被多個監聽器監聽處理
  • 若是事件發佈方法存在事務,那麼事件發佈和事件監聽方法處於同一事務中,屬於同步處理。
  • 可經過onApplicationEvent添加@Async註解變爲異步處理

註解 @EventListener

可在監聽方法上使用@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接收到老師佈置的做業:背誦課文。。
複製代碼
相關文章
相關標籤/搜索