事件流程

  1. 自定义事件,一般是继承ApplicationEvent抽象类
  2. 定义事件监听器,一般是实现ApplicationListener接口
  3. 发布事件
/**
 * Description:定义事件
 * Created by 大师兄 on 2023/10/23 20:22
 */
public class MyApplicationEvent extends ApplicationEvent {
    public MyApplicationEvent(Object source) {
        super(source);
    }
}
/**
 * Description:定义事件监听器
 * Created by 大师兄 on 2023/10/23 20:24
 */
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {

    @Override
    public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
        System.out.println("操作事件:"+myApplicationEvent.getSource().toString());
    }
}
@SpringBootApplication
public class Test {

	public static void main(String[] args) {
		//SpringApplication.run(Test.class, args);

		SpringApplication app =new SpringApplication(Test.class);
		//启动时需要发监听器加到spring容器中(或者直接在监听器上加@Component)
		app.addListeners(new MyApplicationListener());
		ConfigurableApplicationContext context =app.run(args);
		//发布事件
		context.publishEvent(new MyApplicationEvent("我是一个事件!"));
		context.close();
	}

}

console:

操作事件:我是一个事件!
2023-11-05 13:07:42.076  INFO 4660 --- [           main] 

Process finished with exit code 0

还可以通过配置项来配置监听器:

context:listener:classes: com\sycc\event\MyApplicationListener

@EventListener

将一个方法标记为监听器,用于监听应用程序事件,且该类也要注册到容器中

可以通过 condition 属性指定一个SpEL表达式,如果返回 "true", "on", "yes", or "1" 中的任意一个,则事件会被处理,否则不会。

示例:

单一事件监听器

发布事件:

@Service
public class EventPublisher {

    private ApplicationEventPublisher  eventPublisher;

    @Autowired
    public void setEventPublisher(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void publishPersonSaveEvent(){
        //新建一个事件
        PersonSaveEvent  saveEvent = new PersonSaveEvent();
        saveEvent.setId(1);
        saveEvent.setName("i余数");
        saveEvent.setAge(18);
        eventPublisher.publishEvent(saveEvent);
    }
}

监听 事件 :

@Slf4j
@Service
public class EventListenerService {

    @EventListener
    public void handleForPersonSaveEvent(PersonSaveEvent saveEvent){
        log.info("saveEvent -> {}", saveEvent);
    }
}

结果:

只处理id等于1的 -> PersonSaveEvent(id=1, name=i余数, age=18)

使用classes实现多事件监听器

发布事件
在上一个示例的基础上,再多加一个PersonUpdateEvent事件。
public void publishPersonUpdateEvent(){
    PersonUpdateEvent  updateEvent = new PersonUpdateEvent();
    updateEvent.setId(1);
    updateEvent.setName("i余数");
    updateEvent.setAge(19);
    eventPublisher.publishEvent(updateEvent);
}

监听事件

@EventListener(classes = {PersonSaveEvent.class, PersonUpdateEvent.class})
public void handleForPersonSaveAndUpdateEvent(Object event){
    log.info("multi handle event -> {}", event);
}

验证结果
可以监听到多个事件

multi handle event -> PersonSaveEvent(id=1, name=i余数, age=18)
multi handle event -> PersonUpdateEvent(id=1, name=i余数, age=19)

使用condition筛选监听的事件

public void publishPersonSaveEvent(){
    PersonSaveEvent  saveEvent = new PersonSaveEvent();
    saveEvent.setId(1);
    saveEvent.setName("i余数");
    saveEvent.setAge(18);
    eventPublisher.publishEvent(saveEvent);

    PersonSaveEvent  saveEvent2 = new PersonSaveEvent();
    saveEvent2.setId(2);
    saveEvent2.setName("i余数");
    saveEvent2.setAge(18);
    eventPublisher.publishEvent(saveEvent2);
}

监听事件:

@EventListener(condition = "#root.event.getPayload().getId() == 1")
public void handleByCondition(PersonSaveEvent saveEvent){
    log.info("只处理id等于1的 -> {}", saveEvent);
}

结果验证
id为2的事件不满足条件,所以不会执行。

只处理id等于1的 -> PersonSaveEvent(id=1, name=i余数, age=18)

有返回值的监听器

返回一个单一对象

发布事件

public void publishPersonSaveEvent(){
    PersonSaveEvent  saveEvent = new PersonSaveEvent();
    saveEvent.setId(1);
    saveEvent.setName("i余数");
    saveEvent.setAge(18);
    eventPublisher.publishEvent(saveEvent);
}

监听事件

@EventListener
public void handleForPersonUpdateEvent(PersonUpdateEvent updateEvent){
    log.info("handle update event -> {}", updateEvent);
}


@EventListener
public PersonUpdateEvent handleHaveReturn(PersonSaveEvent saveEvent){
    log.info("handle save event -> {}", saveEvent);
    PersonUpdateEvent updateEvent = new PersonUpdateEvent();
    updateEvent.setId(saveEvent.getId());
    updateEvent.setName(saveEvent.getName());
    updateEvent.setAge(saveEvent.getAge());
    return updateEvent;
}

验证结果
可以看到我们监听到了2个事件,PersonSaveEvent是我们主动发布的事件,PersonUpdateEventhandleHaveReturn 方法的返回值,会被 Spring 自动当作一个事件被发送。

handle save event -> PersonSaveEvent(id=1, name=i余数, age=18)
handle update event -> PersonUpdateEvent(id=1, name=i余数, age=18)
返回一个集合

将监听器稍作修改,使其返回一个集合。

@EventListeners
public List<PersonUpdateEvent> handleHaveReturn(PersonSaveEvent saveEvent){
    log.info("handle save event -> {}", saveEvent);
    List<PersonUpdateEvent> events = new ArrayList<>();
    PersonUpdateEvent updateEvent = new PersonUpdateEvent();
    updateEvent.setId(saveEvent.getId());
    updateEvent.setName(saveEvent.getName());
    updateEvent.setAge(saveEvent.getAge());
    events.add(updateEvent);

    PersonUpdateEvent updateEvent2 = new PersonUpdateEvent();
    BeanUtils.copyProperties(updateEvent, updateEvent2);
    events.add(updateEvent2);
    return events;

}

查看结果可以发现,集合中的每个对象都被当作一个单独的事件进行发送。

handle save event -> PersonSaveEvent(id=1, name=i余数, age=18)
handle update event -> PersonUpdateEvent(id=1, name=i余数, age=18)
handle update event -> PersonUpdateEvent(id=1, name=i余数, age=18)