在springboot 应用中,使用监听器有servlet容器的,有spring的
一:先看springboot中怎么使用servlet的监听器(servlet容器中的)
定义servlet监听器
package com.hzt.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* servlet的监听器的使用
*/
@WebListener//标识这是servelt的监听器
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("web===================");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("web down================");
}
}
在springboot启动使用或在一个配置类上加扫描
package com.hzt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan("com.hzt")//servlet监听器的使用
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
二:再看springboot使用spring的监听器
首先定义spring监听器
@Component
public class SpringSelfListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent ApplicationEvent) {
System.out.println("spring监听本身事件========="+ApplicationEvent);
}
}
启动springboot
@SpringBootApplication
@ServletComponentScan("com.hzt")//servlet监听器的使用
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
看springboot启动时,监听自己的事件,servlet监听事件早于spring的
spring监听本身事件=========org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3024e88e: startup date [Wed Jul 24 14:55:43 CST 2019]; root of context hierarchy]
2019-07-24 14:55:46.901 INFO 13132 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
spring监听本身事件=========org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent[source=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer@7ff8a3d6]
spring监听本身事件=========org.springframework.boot.context.event.ApplicationReadyEvent[source=org.springframework.boot.SpringApplication@731eed27]
2019-07-24 14:55:46.906 INFO 13132 --- [ restartedMain] com.hzt.Application : Started Application in 4.261 seconds (JVM running for 5.225)
下面学习spring的监听机制:
1.监听器一定是监听某事件,看spring事件源码
package org.springframework.context;
import java.util.EventObject;
public abstract class ApplicationEvent extends EventObject {
private static final long serialVersionUID = 7099057708183571937L;
private final long timestamp = System.currentTimeMillis();
public ApplicationEvent(Object source) {
super(source);
}
public final long getTimestamp() {
return this.timestamp;
}
}
可以知道,spring事件继承java的对象事件EventObject ,同时知道创建对象时,一定要有事件源,就是谁(事件源)身上发生了什么事情(事件)
2.spring的监听器
package org.springframework.context;
import java.util.EventListener;
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E var1);
}
可知,spring的监听器继承java监听器EventListener,java的监听器是一个标识接口,里面什么也没有
package java.util;
/**
* A tagging interface that all event listener interfaces must extend.
* @since JDK1.1
*/
public interface EventListener {
}
spring的监听器,泛型设定为spring的事件,自然spring的监听器就监听spring的事件
3.spring事件有哪些?如下
从springboot启动日志可知,springboot启动后就发生以下事件(按顺序)
ContextRefreshedEvent:应用刷新事件
EmbeddedServletContainerInitializedEvent:内嵌Servlet容器初始化事件
ApplicationReadyEvent:spring Application启动完成事件
自定义spring监听器和自定义spring事件
自定义spring事件
package com.hzt.listener;
import org.springframework.context.ApplicationEvent;
public class MySpringEvent extends ApplicationEvent {
public MySpringEvent(Object source) {
super(source);
}
}
自定义spring监听器,监听自定义事件
package com.hzt.listener;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MySpringListener implements ApplicationListener<MySpringEvent> {
@Override
public void onApplicationEvent(MySpringEvent mySpringEvent) {
System.out.println("spring监听自定义的事件======"+mySpringEvent.getClass());
}
}
同时还有spring监听器监听本身事件
@Component
public class SpringSelfListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent ApplicationEvent) {
System.out.println("spring监听本身事件========="+ApplicationEvent);
}
}
springboot启动
@SpringBootApplication
@ServletComponentScan("com.hzt")//servlet监听器的使用
public class Application {
/*public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}*/
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
context.publishEvent(new MySpringEvent(new Object()));//发布事件
}
}
spring监听本身事件=========org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@8940838: startup date [Wed Jul 24 15:23:15 CST 2019]; root of context hierarchy]
2019-07-24 15:23:19.282 INFO 12464 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
spring监听本身事件=========org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent[source=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer@16a7f909]
spring监听本身事件=========org.springframework.boot.context.event.ApplicationReadyEvent[source=org.springframework.boot.SpringApplication@6717ce81]
2019-07-24 15:23:19.289 INFO 12464 --- [ restartedMain] com.hzt.Application : Started Application in 4.485 seconds (JVM running for 5.503)
spring监听自定义的事件======class com.hzt.listener.MySpringEvent
spring监听本身事件=========com.hzt.listener.MySpringEvent[source=java.lang.Object@1492c960]
可知,springboot发布事件是找到所有相关的监听器,调用其监听方法,把事件作为参数传输
如果在监听方法里,传输的事件是ApplicationEvent,那么当前该spring监听器可以监听所有spring事件,因为spring事件都继承ApplicationEvent
当自定义spring监听器时,一定要想好这个监听器是监听什么事件,而不是直接在监听方法里面写ApplicationEvent参数
如果写ApplicationEvent参数,就是代表所有的只要继承spring事件ApplicationEvent的都监听.
从事件里一定是可以拿到事件源的