ApplicationListener监听器



 

public class EmailEvent extends ApplicationEvent {
    private String address;
    private String text;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public EmailEvent(Object source, String address, String text) {
        super(source);
        this.address = address;
        this.text = text;
    }

    public EmailEvent(Object source) {
        super(source);
    }

//......address和text的setter、getter

}



//容器刷新监听
@Component
public class TestApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
    Logger log = LoggerFactory.getLogger(TestApplicationListener.class);
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        log.info(contextRefreshedEvent.toString());
        log.info("TestApplicationListener..................................");
    }
}


@Component
//public class EmailNotifier implements ApplicationListener {
public class EmailNotifier implements ApplicationListener<EmailEvent> {
    Logger log = LoggerFactory.getLogger(EmailNotifier.class);

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        //if (event instanceof EmailEvent) {
            EmailEvent emailEvent = (EmailEvent) event;
            log.info("邮件地址:" + emailEvent.getAddress());
            log.info("邮件内容:" + emailEvent.getText());
        //} else {
        //    log.info("容器本身事件:" + event);
        //}
    }



//注解方式
@Component
public class EmailNotifier {
    Logger log = LoggerFactory.getLogger(EmailNotifier.class);

  @EventListener(EmailEvent.class)
    public void onApplicationEvent(ApplicationEvent event) {
            EmailEvent emailEvent = (EmailEvent) event;
            log.info("邮件地址:" + emailEvent.getAddress());
            log.info("邮件内容:" + emailEvent.getText());
    }
@SpringBootTest(classes = Springapplication22.class)    //springboot启动类,依靠启动类找扫描springcontext的bean
@RunWith(SpringRunner.class)
public class ListenerTest {
    @Autowired
    ApplicationContext context;

    @Test
    public void test1() {
        //创建一个ApplicationEvent对象
        EmailEvent event = new EmailEvent("hello", "abc@163.com", "This is a test");
        //主动触发该事件
        context.publishEvent(event);
    }
}

 贴个主要的源码

Spring 中事件发布都是通过SimpleApplicationEventMulticaster来实现的

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {
                                // 异步
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
				invokeListener(listener, event);
			}
		}
	}

可以看出,如果设置了Executor则异步发送,否则同步;而且可以看出通过 resolveDefaultEventType(event) 对发布的事件类型进行了校验,这就是为什么我们可以直接使用泛型来指定我们想接收的事件对象, 比如上面的ApplicationListener<MyApplicationEvent>。

也就是说发布事件event后,会找到对应事件的event的listener,发出通知。

如果没有加泛型,事件发生都会得到通知。

Spring内建事件

    • ContextRefreshedEvent: Spring应用上下文就绪事件;
    • ContextStartedEvent: Spring应用上下文启动事件;
    • ContextStopedEvent: Spring应用上下文停止事件;
    • ContextClosedEvent: Spring应用上下文关闭事件;

参考:https://zhuanlan.zhihu.com/p/145927110

原文地址:https://www.cnblogs.com/chenfx/p/15092475.html