1.为什么要把数据字典和基础数据放在ServletContext?
因为数据字典是,整个网站使用的是同一份。所以可以在网站启动的时候,就查询放在ServletContext里面就可以。这样就不用每次请求过来的时候再多次查询数据库。
--使用过滤, 不好。 因为此次请求过来,都必须要拦截过滤器。
--使用Servlet , 不好, 因为此次请求过来,都必须要执行对应路径的servlet
--所以,我们需要有一个技术。在启动Tomcat的时候就加载一次,后面就不会再加载了。
2.需要解决的问题
问题1:创建Spring容器是需要指定配置文件或者配置类的位置的。而监听器是没有设置初始化参数的入口的。如何解决?
答:通过<context-param>可以将参数放在全局的context容器里面。那么所有的web组件的对象都可以访问了。
问题2:监听器是属于Tomcat Web服务器的技术,所以对象并没有放在Spring容器里面。是无法通过注入的方式获得Spring容器的对象的。如何在监听器里面获得Spring容器的对象呢?
答:对于不是Spring容器里面的对象要获得Spring容器里面的对象。Spring框架提供了一个WebApplicationContextUtils工具类可以获得Spring容器的对象。
package cn.gzsxt.listener; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import cn.gzsxt.service.DictionaryService; public class DictionaryCreateListener implements ServletContextListener { //@Autowired //private DictionaryService dictionaryService; @Override public void contextInitialized(ServletContextEvent sce) { // WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()); DictionaryService dictionaryService = applicationContext.getBean(DictionaryService.class); List<Map<String, Object>> dictionarys = dictionaryService.findAllDictionary(); ServletContext context = sce.getServletContext(); context.setAttribute("dictionarys", dictionarys); } @Override public void contextDestroyed(ServletContextEvent sce) { } }
web.xml的配置
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd "> <!-- 配置编码过滤器 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!-- 指定编码 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置核心控制器 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定配置类的路径,如果在监听器配置的Spring容器,那么这里不要配置了,但是也不能删除该参数, 因为如果删除了该参数,SpringMVC可以自动寻找/WEB-INF/dispatcherServlet-servlet.xml配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <!-- 路径如果是一个包名,会加载该包里面的所有配置类 --> <param-value></param-value> </init-param> <!-- 指定支持注解的容器 --> <init-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 注意事项:如果使用servlet启动spring容器。那么spring容器用于后于listener容器的创建。 --> <!-- 如果需要在listener加载里面获得Spring容器,那么我们必须要spring 容器创建在这个listener之前--> <!-- 问题1:如果如何让spring 容器在DictionaryCreateListener监听器之前创建呢? 答:那么我们只能使用listener来启动spring框架 问题2:Spring创建容器必须要配置类或者配置文件,而监听器是没有设置初始化参数的标签的。怎么办? 答:可以配置全局的参数来让监听器访问 --> <!-- 指定配置类的位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>cn.gzsxt.config</param-value> </context-param> <!-- 指定Spring容器的类型 --> <context-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置数据字典监听器,启动Tomcat的那一刻就查询数据字典,并且放在上下文容器里面 --> <listener> <listener-class>cn.gzsxt.listener.InitDataCreateListener</listener-class> </listener> </web-app>