监听器
实现方式:实现ApplicationListener接口并注入;在方法加注解@EventListener,注入该类;@WebListener+@ServletCompentScan注解开启servlet组件扫描
1,事件对象
//事件携带对象,可以被发布
public class EventObject {
//观察者对象
protected transient Object source;
public EventObject(Object source);
}
//应用事件,定义了创建时间戳的属性
public abstract class ApplicationEvent extends EventObject {
private final long timestamp = System.currentTimeMillis();
public ApplicationEvent(Object source)
}
//ServletWebServerInitialiedEven 事件对象,在Springboot中其对象初始化
//为source/webServer为TomcatWebServer
// applicationContext为AnnotationConfigServletWebServerApplicationContext 事件发布对象
public class ServletWebServerInitializedEvent {
private final ServletWebServerApplicationContext applicationContext;
public ServletWebServerInitializedEvent(WebServer webServer, ServletWebServerApplicationContext applicationContext);
}
ApplicationEventMulticaster 事件广播器,用来通知所有观察者对象
public interface ApplicationEventMulticaster {
//添加/移除ApplicationListener和ApplicationListenerBean
//派发事件
void multicastEvent(ApplicationEvent var1);
void multicastEvent(ApplicationEvent var1, @Nullable ResolvableType var2);
}
// 1,在对象节点处,调用AnnotationConfigServletWebServerApplicationContext.publishEvent
// 2,在AbstractApplicationContext类initApplicationEventMulticaster()方法中
// defaultListableBeanFactory中会判断
// containsLocalBean("applicationEventMulticaster")
// 没有,就new SimpleApplicationEventMulticaster。
// 3,在AbstractApplicationContex类中调用this.publishEvent(event, (ResolvableType)null)
// 方法中获取到SimpleApplicationEventMulticaster对象实例,并调用multicastEvent()方法
// 注册ApplicationListener=ApplicationListenerMethodAdapter监听器
public class SimpleApplicationEventMulticaster {
// map中的key 为ListenerCacheKey类,其属性
// ResolvableType eventType例如ServletWebServerInitializedEvent.class
// Class<?> sourceType例如TomcatWebServer
// value为ListenerRetriever类,其属性
// Set<ApplicationListener<?>> applicationListeners 存放事件对象对应listners
// Set<String> applicationListenerBeans
final Map<AbstractApplicationEventMulticaster.ListenerCacheKey, AbstractApplicationEventMulticaster.ListenerRetriever> retrieverCache
// map存放所有对象的锁
retrievalMutex
// 存放各种类型的监听器对象
ListenerRetriever defaultRetriever
// AnnotationConfigServletWebServerApplicationContext的实例对
// 象.publish(ApplicationEvent event,ResolvableType null)方法
publish(event, ResolvableType eventType)->{
1.如果event为ApplicationEvent的接口,则applicationEvent=event
否则applicationEvent = new PayloadApplicationEvent(this, event)且eventType
= (PayloadApplicationEvent)applicationEvent.getResolvableType()
2.this=earlyApplicationEvents如果不为空,则向其中加入applicationEvent
为null,则调用
SimpleApplicationEventMulticaster.multicastEvent(applicationEvent,null)->{
// type 属性eventType为事件对象的字节码对象,sourceType 为事件对象的源对象
ResolvableType type=this.resolveDefaultEventType(event);
// 得到事件对象对应的监听器对象
getApplicationListeners(event, type)->{
// 根据eventType, sourceType,构建 cacheKey 对象
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceTyp)
// 根据 cacheKey 的到对应的监听器
ListenerRetriever retriever = retrieverCache.get(cacheKey);
// 如果不为null,则返回,为null,则new ListenerRetriever对象存放监听器
retriever = new ListenerRetriever(true);
// 根据条件,检索监听器
listeners = this.retrieveApplicationListeners(eventType, sourceType,
retriever)->{
// 得到this.defaultRetriever中各种类型监听器listeners
// 循环迭代每一个listener,
// 条件为supportsEvent(listener, eventType,
// sourceType)->{
// //如果listener为GenericApplicationListener实例
// // 则强转为其类型,否则 new
// // GenericApplicationListenerAdapter(listener)
// // 赋值给smartListener
// GenericApplicationListener smartListener;
// retrun smartListener.supportsEventType(eventType) &&
// smartListener.supportsSourceType(eventType);
// }
// 成立,则向retriever中添加对象,allListeners添加对象用于返回
}
//放入retrieverCache
this.retrieverCache.put(cacheKey, retriever);
}
//循环匹配到的监听器
listener.onApplicationEvent(event);
}
}
}
EventListener
// RequestContextListener父类接口ServletRequestListener父类接口EventListener
// RequestContextListener对应的事件对象ServletRequestEvent,其属性ServletRequest request
/ RequestContextListener 事件分为requestInitialized事件和requestDestroyed事件
public class RequestContextListener {
//请求来到时,调用该方法。
public void requestInitialized(ServletRequestEvent requestEvent) {
//从事件对象requestEvent中获得HttpServletRequest实例对象
HttpServletRequest request = (HttpServletRequest)requestEvent.getServletRequest();
//初始化ServletRequestAttributes对象
ServletRequestAttributes attributes = new ServletRequestAttributes(request);
request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
LocaleContextHolder.setLocale(request.getLocale());
//将ServletRequestAttributes放到TheadLocal中
//通过RequestContextHolder的静态方法可以在任何地方拿到request/response对象
RequestContextHolder.setRequestAttributes(attributes);
}
}
//从这个类方法和构造方法,可以得出这个类主要就是获得请求和响应对象
public class ServletRequestAttributes {
public ServletRequestAttributes(HttpServletRequest request);
public ServletRequestAttributes(HttpServletRequest request, @Nullable HttpServletResponse response)
Object getAttribute(String name, int scope);
HttpServletRequest getRequest();
HttpServletResponse getResponse()
}
过滤器
自定义过滤器方式:@WebFilter注解+@ServletCompentScan注解开启servlet组件扫描或实现Filter接口+FilterRegistrationBean。
过滤器中的void init(FilterConfig filterConfig)方法在应用启动的时候调用,filterConfig的实例为ApplicationFilterConfig,可以得到ServletContext实例对象。
//Filter的主要逻辑编写的地方
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain){
//执行下一个过滤器之前的逻辑
preDoSomeThing();
//执行下一个过滤器
filterChain.doFilter(servletRequest,servletResponse);
//所有过滤器执行完之后的逻辑
finalDoSomeThing();
//假设共有Filter1,Filter2过滤器,执行顺序filter1.preDoSomeThing()
// ->filter2.preDoSomeThing()->filter2.finalDoSomeThing()
// ->filter1.finalDoSomeThing()
}
拦截器
实现方式:实现HandlerInterceptor接口+重写WebMvcConfigurer的addInterceptors()方法将实例对象注入到InterceptorRegistry中;继承HandlerInterceptorAdapter实现preHandle()方法+继承(过期不建议使用)WebMvcConfigurerAdapter类addIntercepters()注册拦截器。
public interface HandlerInterceptor {
//调用doDispatch(HttpServletRequest request, HttpServletResponse response)方法
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
public class DispatcherServlet {
this.doService(request, response){
//分发请求
this.doDispatch(request, response){
//mappedHandler对象里包含HandlerInterceptor的实例对象ArrayList
HandlerExecutionChain mappedHandler = getHandler(HttpServletRequest request);
//1.调用HandlerInterceptor中的preHandle方法。里面数组递增迭代调用(多个)
mappedHandler.applyPreHandle(processedRequest, response){
HandlerInterceptor[] interceptors = this.getInterceptors();
//循环遍历interceptors,执行preHandle
interceptor.preHandle(request, response, this.handler);
}
//2.真正执行逻辑的代码
mv = ha.handle(processedRequest, response, mappedHandler.getHandler())
//3.调用HandlerInterceptor中的postHandle方法。里面数组递减迭代调用(多个)
mappedHandler.applyPostHandle(processedRequest, response, mv);
//4.调用HandlerInterceptor中的afterCompletion方法。里面数组递减迭代调用(多个)
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
};
};
}
总结:一个请求经过1.ApplicationFilterChain类中的所有filters的过滤器入栈执行filter.doFilter()前preDoSomeThing();2.ApplicationFilterChain.doFilter()->ApplicationFilterChain.internalDoFilter()->ApplicationFilterChain.servlet.service(request, response)其servlet=DispatcherServlet;3.DispatcherServlet.service()方法里会调上图代码中DispatcherServlet.doService(request, response)方法中,该方法做了递增循环拦截器(preHandle)->进入请求逻辑实现->递减循环拦截器(postHandle)->递减循环拦截器(afterCompletion) ;4.出栈执行filter.doFilter()后finalDoSomeThing()。