1.监视器

  (1)首先监视器是观察者模式的实现,在我之前的博客中有关于监视器模式的解释。监视器相当于观察者

  (2)我们在springMvc中最常见的监视器 ContextLoaderlistener

  1. <listener>
  2. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  3. </listener>

    (3)我们来看看ContextLiaderListener(当某件事情发生后,调用这个方法来初始化spring父容器与springMvc子容器)

   

  1. @Override
  2. public void contextInitialized(ServletContextEvent event) {
  3. initWebApplicationContext(event.getServletContext());
  4. }

2.过滤器与拦截器(过滤器与拦截器相似,只是作用的地方不同)

  (1).在之前的博客中说过Servlet的service方法是在ApplicationFilterChain中。我们来看看这个类中的方法

  1. private void internalDoFilter(ServletRequest request,
  2. ServletResponse response)
  3. throws IOException, ServletException {
  4.  
  5. // Call the next filter if there is one
  6. if (pos < n) {
  7. ApplicationFilterConfig filterConfig = filters[pos++];
  8. try {
  9. Filter filter = filterConfig.getFilter();
  10.  
  11. if (request.isAsyncSupported() && "false".equalsIgnoreCase(
  12. filterConfig.getFilterDef().getAsyncSupported())) {
  13. request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE);
  14. }
  15. if( Globals.IS_SECURITY_ENABLED ) {
  16. final ServletRequest req = request;
  17. final ServletResponse res = response;
  18. Principal principal =
  19. ((HttpServletRequest) req).getUserPrincipal();
  20.  
  21. Object[] args = new Object[]{req, res, this};
  22. SecurityUtil.doAsPrivilege ("doFilter", filter, classType, args, principal);
  23. } else {
  24. filter.doFilter(request, response, this); //在这里调用了过滤器的doFilter()方法
  25. }
  26. } catch (IOException | ServletException | RuntimeException e) {
  27. throw e;
  28. } catch (Throwable e) {
  29. e = ExceptionUtils.unwrapInvocationTargetException(e);
  30. ExceptionUtils.handleThrowable(e);
  31. throw new ServletException(sm.getString("filterChain.filter"), e);
  32. }
  33. return;
  34. }
  35.  
  36. // We fell off the end of the chain -- call the servlet instance
  37. try {
  38. if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
  39. lastServicedRequest.set(request);
  40. lastServicedResponse.set(response);
  41. }
  42.  
  43. if (request.isAsyncSupported() && !servletSupportsAsync) {
  44. request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,
  45. Boolean.FALSE);
  46. }
  47. // Use potentially wrapped request from this point
  48. if ((request instanceof HttpServletRequest) &&
  49. (response instanceof HttpServletResponse) &&
  50. Globals.IS_SECURITY_ENABLED ) {
  51. final ServletRequest req = request;
  52. final ServletResponse res = response;
  53. Principal principal =
  54. ((HttpServletRequest) req).getUserPrincipal();
  55. Object[] args = new Object[]{req, res};
  56. SecurityUtil.doAsPrivilege("service",
  57. servlet,
  58. classTypeUsedInService,
  59. args,
  60. principal);
  61. } else {
  62. servlet.service(request, response); //在这里调用service方法
  63. }
  64. } catch (IOException | ServletException | RuntimeException e) {
  65. throw e;
  66. } catch (Throwable e) {
  67. e = ExceptionUtils.unwrapInvocationTargetException(e);
  68. ExceptionUtils.handleThrowable(e);
  69. throw new ServletException(sm.getString("filterChain.servlet"), e);
  70. } finally {
  71. if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
  72. lastServicedRequest.set(null);
  73. lastServicedResponse.set(null);
  74. }
  75. }
  76. }

也就是说我们的过滤器的doFilter()方法是在Servlet的service方法之前调用的。

(2)我们再来看看拦截器

  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
  2. HttpServletRequest processedRequest = request;
  3. HandlerExecutionChain mappedHandler = null;
  4. boolean multipartRequestParsed = false;
  5.  
  6. WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
  7.  
  8. try {
  9. ModelAndView mv = null;
  10. Exception dispatchException = null;
  11.  
  12. try {
  13. processedRequest = checkMultipart(request);
  14. multipartRequestParsed = (processedRequest != request);
  15.  
  16. // Determine handler for the current request.
  17. mappedHandler = getHandler(processedRequest);
  18. if (mappedHandler == null || mappedHandler.getHandler() == null) {
  19. noHandlerFound(processedRequest, response);
  20. return;
  21. }
  22.  
  23. // Determine handler adapter for the current request.
  24. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
  25.  
  26. // Process last-modified header, if supported by the handler.
  27. String method = request.getMethod();
  28. boolean isGet = "GET".equals(method);
  29. if (isGet || "HEAD".equals(method)) {
  30. long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
  31. if (logger.isDebugEnabled()) {
  32. logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
  33. }
  34. if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
  35. return;
  36. }
  37. }
  38.  
  39. if (!mappedHandler.applyPreHandle(processedRequest, response)) {     //在这里调用了拦截器中的preHandler()方法
  40. return;
  41. }
  42.  
  43. // Actually invoke the handler.
  44. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //在这里调用Controller中的方法
  45.  
  46. if (asyncManager.isConcurrentHandlingStarted()) {
  47. return;
  48. }
  49.  
  50. applyDefaultViewName(processedRequest, mv);
  51. mappedHandler.applyPostHandle(processedRequest, response, mv);        //在这里调用了拦截器的postHandler()方法
  52. }
  53. catch (Exception ex) {
  54. dispatchException = ex;
  55. }
  56. catch (Throwable err) {
  57. // As of 4.3, we're processing Errors thrown from handler methods as well,
  58. // making them available for @ExceptionHandler methods and other scenarios.
  59. dispatchException = new NestedServletException("Handler dispatch failed", err);
  60. }
  61. processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
  62. }
  63. catch (Exception ex) {
  64. triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
  65. }
  66. catch (Throwable err) {
  67. triggerAfterCompletion(processedRequest, response, mappedHandler,
  68. new NestedServletException("Handler processing failed", err));
  69. }
  70. finally {
  71. if (asyncManager.isConcurrentHandlingStarted()) {
  72. // Instead of postHandle and afterCompletion
  73. if (mappedHandler != null) {
  74. mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
  75. }
  76. }
  77. else {
  78. // Clean up any resources used by a multipart request.
  79. if (multipartRequestParsed) {
  80. cleanupMultipart(processedRequest);
  81. }
  82. }
  83. }
  84. }

也就是说拦截器的方法是在controller中的方法调用前后被调用的。

3.总结:

  (1)监听器是观察者模式的实现

  (2)过滤器与拦截器相似,只不过过滤器是在service()方法被调用前调用的,而拦截器是在Controller中的方法被调用前调用的。

spring中的监视器,过滤器,拦截器的更多相关文章

  1. JavaWeb中监听器+过滤器+拦截器区别、配置和实际应用

    JavaWeb中监听器+过滤器+拦截器区别.配置和实际应用 1.前沿上一篇文章提到在web.xml中各个元素的执行顺序是这样的,context-param-->listener-->fil ...

  2. MVC中的过滤器/拦截器怎么写

    创建一个AuthenticateFilterAttribute(即过滤器/拦截器) 引用System.Web.Mvc; public class AuthenticateFilterAttribute ...

  3. Spring AOP 源码分析 - 拦截器链的执行过程

    1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...

  4. 通过spring抽象路由数据源+MyBatis拦截器实现数据库自动读写分离

    前言 之前使用的读写分离的方案是在mybatis中配置两个数据源,然后生成两个不同的SqlSessionTemplate然后手动去识别执行sql语句是操作主库还是从库.如下图所示: 好处是,你可以人为 ...

  5. Spring AOP深入理解之拦截器调用

    Spring AOP深入理解之拦截器调用 Spring AOP代理对象生成回想 上一篇博客中:深入理解Spring AOP之二代理对象生成介绍了Spring代理对象是怎样生成的,当中重点介绍了JDK动 ...

  6. SpringBoot 过滤器, 拦截器, 监听器 对比及使用场景

    1. 过滤器 (实现 javax.servlet.Filter 接口) ① 过滤器是在web应用启动的时候初始化一次, 在web应用停止的时候销毁. ② 可以对请求的URL进行过滤, 对敏感词过滤, ...

  7. spring自定义注解实现登陆拦截器

    1.spring自定义注解实现登陆拦截器 原理:定义一个注解和一个拦截器,拦截器拦截所有方法请求,判断该方法有没有该注解.没有,放行:有,要进行验证.从而实现方法加注解就需要验证是否登陆. 2.自定义 ...

  8. vue中怎样实现 路由拦截器

    vue中怎样实现 路由拦截器(当用户没有登录的时候,跳转到登录页面,已经登录的时候,不能跳转到登录页,除非后台token失效) 在 我们需要实现这样 一个功能,登录拦截 其实就是 路由拦截,首先在定义 ...

  9. 【spring boot】在自定义拦截器中从request中获取json字符串

    又这样的需求,需要在自定义的拦截器中获取request中的数据,想获取到的是JSON字符串 那需要在拦截器中写这样一个方法 public static String getOpenApiRequest ...

随机推荐

  1. Python自动化面试必备 之 你真明白装饰器么?

    Python自动化面试必备 之 你真明白装饰器么? 装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以这也是Python面试中必问的问题,但对于好多小白来讲,这个功能 有点绕 ...

  2. 项目管理心得:一个项目经理的个人体会、经验总结(zz)

    本人做项目经理工作多年,感到做这个工作最要紧的就是要明白什么是因地制宜.因势利导,只有最合适的,没有什么叫对的,什么叫错的,项目经理最忌讳 的就是完美主义倾向,尤其是做技术人员出身的,喜欢寻找标准答案 ...

  3. hdu-2191(完全背包+二进制优化模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 思路:完全背包模板 #include<iostream> #include<c ...

  4. 35. Romantic Love and Ideal Romantic Relationship 爱情及理想爱情关系

    35. Romantic Love and Ideal Romantic Relationship 爱情及理想爱情关系 ① Romantic love has clear evolutionary r ...

  5. arduino IO口

    AVR单片机的每组I/O口都配备有三个8位寄存器,分别是:方向控制寄存器DDRx.数据寄存器PORTx.输入引脚寄存器PINx(x=A/B/C/D).I/O口的工作方式和表现特征由这三个I/O寄存器控 ...

  6. =delete(c++11)

    1.为什么要阻止类对象的拷贝? 1)有些类,不需要拷贝和赋值运算符,如:IO类,以避免多个拷贝对象写入或读取相同的IO缓冲 2.如何阻止? 1)不定义拷贝构造函数和拷贝赋值运算符时,好心的编译器也会及 ...

  7. java拷贝文件到另一个目录下

    package com.util; import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream ...

  8. 按str 存储和按 list 存储

    按str 存储1 w2 = open('./trsd_w.txt','a')#a代表追加 w代表重写 if matcher1: flag = 1 w2.write("\n") fo ...

  9. nexus 组件下载和上传

    一. 重写 super pom 修改 maven 的 settings.xml Configuring Maven to Use a Single Repository Group <setti ...

  10. Mouse Touch Stylus

    Mouse操作: preview mouse down, StylusDevice:null mouse down,StylusDevice:null preview mouse up, Stylus ...