Spring集成web环境
ApplicationContext
问题
应用上下文对象(Spring容器)是通过new ClassPathXmlApplicationContext(“Spring配置文件”)方式获取的,但是每次从容器中获得取Bean时都要编写new ClassPathXmlApplicationContext,这样会导致配置文件加载多次,应用上下文对象ApplicationContext创建多次
解决方法
在Web项目中,可以使用ServletContextListener监听器监听Web应用的启动,可以在Web启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,再将其存到servlet最大的域对象ServletContext中,这样就可以在任意位置从域中获取Spring容器对象了
实现步骤
- 创建Web应用启动监听器,实现ServletContextListener监听器接口
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
// 将Spring的应用上下文对象存到servlet最大的域对象ServletContext中
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("app",app);
System.out.println("Spring容器创建完毕");
}
- 在web.xml中配置监听器
<listener>
<listener-class>com.heima.listener.ContextLoaderListener</listener-class>
</listener>
- 创建Servlet程序(在web.xml中配置servlet),获取Spring应用上下文对象,获取bean对象
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
UserService userService = app.getBean(UserService.class);
userService.save();
}
解耦合优化
在web.xml中配置ServletContext初始化参数,配置Spring配置文件的文件名
<!-- 配置Spring配置文件的文件名 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
在Listener监听器中创建Spring应用上下文对象时,读取并赋予xml中Spring配置文件的地址
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
// 读取web.xml中的全局参数
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext(contextConfigLocation);
// 将Spring的应用上下文对象存到servlet最大的域对象ServletContext中
servletContext.setAttribute("app",app);
System.out.println("Spring容器创建完毕");
}
终!Spring提供获取应用上下文对象的工具类
上面的分析不用手动实现,Spring提供了一个监听器ContextLoaderListener(需导入spring-web依赖)就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个工具类WebApplicationContextUtils以获取Spring应用上下文对象
步骤:
- pom.xml中导入spring-web的jar包依赖
- web.xml中配置ContextLoaderListener监听器
- 使用WebApplicationContextUtils获取Spring应用上下文对象ApplicationContext
1、pom.xml中导入spring-web的jar包依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
2、web.xml中配置ContextLoaderListener监听器
<!-- 配置监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
web.xml中配置Spring配置文件的文件名
<!-- 配置Spring配置文件的文件名 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
3、使用WebApplicationContextUtils获取Spring应用上下文对象ApplicationContext
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserService userService = app.getBean(UserService.class);
userService.save();
}