因此它的完整加载顺序就是 :ServletContext -> context-param -> listener-> filter -> servlet
开发一个监听器, 实现 ServletContextListener 接口
不过有一点需要注意的是: spring 容器的加载要在 servlet 之后, 因此在有些过滤器当中需要提前用到 spring bean 的时候, 就需要改成 Listener 的方式
org.springframework.web.context.ContextLoaderListener
ContextLoaderListener 的作用就是启动 Web 容器时, 自动装配 ApplicationContext 的配置信息. 因为它实现了 ServletContextListener 这个接口, 在 web.xml 配置这个监听器, 启动容器时, 就会默认执行它实现的方法.
容器监听器 ServletContextListener 是 ServletContext 的监听者, 如果 ServletContext 发生变化, 如服务器启动时 ServletContext 被创建, 服务器关闭时 ServletContext 将要被销毁.
要求每次访问 action 都无需加载新的 xml 文件, 利用框架的监听器实现只在服务器启动时加载一次 xml 配置, 用于提高性能.
监听器内如何引用对象:
1, 直接加载 "bean.xml" 文件, bean 被实例化了两次, 不可取.
2, 从 servletcontext 中获取. 解析:(前一步在 contextLoaderListener, 后两步在 contextLoader 中)
- /**
- * Initialize the root web application context.
- */
- public void contextInitialized(ServletContextEvent event) {
- this.contextLoader = createContextLoader();
- // 获取 spring 配置文件, 创建 webapplicationcontext
- this.contextLoader.initWebApplicationContext(event.getServletContext());
- }
- protected ContextLoader createContextLoader() {
- return new ContextLoader();
- }
- <wiz_tmp_tag class="wiz-block-scroll">
- this.context = createWebApplicationContext(servletContext, parent);
- servletContext.setAttribute(
- // 创建好的 spring context 交给 application 内置对象, 使监听器, 过滤器, 拦截器都可以访问.
- WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
- // 获取 spring 配置文件路径
- String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
- if (configLocation != null) {
- wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation, ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
- }
- // 加载 spring 文件
- customizeContext(servletContext, wac);
- wac.refresh();
- return wac;
- // 解决方案二, 项目在启动时, 把 Spring 配置文件通过 Spring 的监听器加载, 存储到 ServletContext 中, 我们只要在 ServletContext 中获取即可.
- // 方法传入对象 ServletContextEvent event
- ApplicationContext context = (ApplicationContext) event.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
- // 工具类 WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
- productService = (ProductService) context.getBean("productService");
- System.out.println(productService);
开发一个过滤器必须实现 java 定义好的 javax.servlet.Filter 接口: (Servlet 的特性)
这一接口含有三个过滤器必须执行的方法:
doFilter(ServletRequest, ServletResponse, FilterChain): 这是一个完成过滤行为的方法. 这同样是上游过滤器调用的方法.
引入的 FilterChain 对象提供了后续过滤器所要调用的信息. 如果该过滤器是过滤器链中的最后一个过滤器, 则将请求交给被请求资源. 也可以直接给客户端返回响应信息.
init(FilterConfig): 由 Web 容器来调用完成过滤器的初始化工作. 它保证了在第一次 doFilter() 调用前由容器调用. 您能获取在 web.xml 文件中指定的初始化参数.
destroy(): 由 Web 容器来调用来释放资源, doFilter() 中的所有活动都被该实例终止后, 调用该方法.
开发一个拦截器必须实现 HandlerInterceptor 接口:
preHandle(): 这个方法在 handler 执行之前被调用, 在该方法中对用户请求 request 进行处理. 如果程序员决定该拦截器对 请求进行拦截处理后还要调用其他的拦截器, 或者是业务处理器去进行处理, 则返回 true; 如果程序员决定不需要再调用其他的组件去处理请求, 则返回 false.
postHandle(): 这个方法在 handler 执行后, 但是 DispatcherServlet 向客户端返回响应前被调用, 在该方法中对用户请求 request 进行处理.
afterCompletion(): 这个方法在 DispatcherServlet 完全处理完请求后被调用, 可以在该方法中进行一些资源清理的操作. view 渲染完成, dispatcherServlet 返回之前执行.
来源: https://www.cnblogs.com/shuchen007/p/9219798.html