Spring(一):利用全局初始化参数解耦ApplicationContext与监听器

前期我们已经创建了监听器,为解决在每次调用Servlet时重复创建决配置文件的问题。

 监听器代码如下

public class ContextLoaderListener implements ServletContextListener {


    public void contextInitialized(ServletContextEvent sce) {
        ApplicationContext app = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        //将spring存入servletcontext域
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("app",app);
        System.out.println("Spring容器创建完毕.......");
    }

    public void contextDestroyed(ServletContextEvent sce) {

    }
}

web层代码如下

public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        ApplicationContext app = new ClassPathXmlApplicationContext("ApplicationContext.xml");


        ServletContext servletContext = req.getServletContext();
        ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");

        UserService userService = app.getBean(UserService.class);
        userService.save();
    }
}

 但ApplicationContext未完成与监听器的解耦,于是我们在xml中引入全局初始化参数


1.修改web.xml

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>ApplicationContext.xml</param-value>
  </context-param>

2.修改监听器

public class ContextLoaderListener implements ServletContextListener {


    public void contextInitialized(ServletContextEvent sce) {

        ServletContext servletContext = sce.getServletContext();
        //读取web.xml中的全局参数
        String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
        //将已有的ApplicationContext传入new中,实现解耦
        ApplicationContext app = new ClassPathXmlApplicationContext(contextConfigLocation);
        //将spring存入servletcontext域

        servletContext.setAttribute("app",app);
        System.out.println("Spring容器创建完毕.......");
    }

    public void contextDestroyed(ServletContextEvent sce) {

    }
}

如此实现了ApplicationContext与监听器的解耦


进一步,为解决每一个服务需要记住attribute名字的问题,我们对代码进行优化,建立了一个工具类完成ApplicationContext的调取,并在Servlet直接调取这个工具类的方法

1.创建工具类如下

public class WebApplicationContextUtils {

    public static ApplicationContext getWebApplicationContext(ServletContext servletContext){
        return (ApplicationContext) servletContext.getAttribute("app");
    }

}

2.Servlet引用如下

public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        ApplicationContext app = new ClassPathXmlApplicationContext("ApplicationContext.xml");


        ServletContext servletContext = req.getServletContext();
//        ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService = app.getBean(UserService.class);
        userService.save();
    }
}

以上优化无需手动书写,Spring已经提供了监听器对上述功能进行封装(写到这我才知道Spring有了这个功能,淦!)

只需三步

1.在pom.xml中加载spring-web

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>

2.在web.xml中配置ContextLoaderListener


  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:ApplicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

3.使用WebApplicationContextUtils获得应用上下文

public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        ApplicationContext app = new ClassPathXmlApplicationContext("ApplicationContext.xml");


        ServletContext servletContext = req.getServletContext();
//        ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
//        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);

        WebApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService = app.getBean(UserService.class);
        userService.save();
    }
}

此文为黑马SSM视频教学笔记,建议配合使用。

上一篇:2021-10-28


下一篇:ssm整合配置文件