在Web项目中当Web容器启动时我们要同时启动Spring容器,有三种办法,第一种使用监听器启动,第二使用Servlet启动,第三使用MVC框架的扩展点启动,这里主要选择第一种,因为监听器的启动时机早于Servlet。强烈建议使用办法一。
我们需要使用到Spring定义好的一个监听器:org.springframework.web.context.ContextLoaderListener,该监听器在包Spring-web.x.x.x.jar下,修改pom.xml文件,添加依赖:
org.springframework spring-web ${spring.version}
修改web.xml文件,新增监听器声明,代码如下:
Spring容器启动监听器 org.springframework.web.context.ContextLoaderListener
当监听器在启动Spring容器时会自动查找Web-INF/lib目录下名为applicationContext.xml配置文件,当然也可以设置参数指定配置文件的具体位置,特别是有多个配置文件的情况,指定办法如下:
Spring容器加载监听器 org.springframework.web.context.ContextLoaderListener contextConfigLocation classpath*:applicationContext.xml
如果有多个配置文件则可以通过逗号分开。怎么判断是否启动成功,则可以参考本文第二点,获得ApplicationContext实例,也可以查看tomcat启动时的信息,如果没有出现错误且能找到如下说明基本成功。
启动失败也有几种可能,如applicationContext.xml文件的路径错误;找不到类ContextLoaderListener;如果提示找不到类,很可能是因为没有将Maven依赖的包发布出去,可以在项目属性中设置,如下所示:
方法与1.1基本相同,只是配置有小的区别,修改web.xml的具体内容如下:
context org.springframework.web.context.ContextLoaderServlet 1 servlet >contextConfigLocation classpath:beans1.xml,classpath:beans2.xml...
需要注意的是两者都是继承类ContextLoader,但从Spring3.0开始已经移除了ContextLoaderServlet,用ContextLoaderListener的方式替代。第3种启动方式只有在特定的框架中才有效,所以不多用。
当web容器启动时Spring容器如果也成功启动了,则可以在整个web应用程序中获得ApplicationContext完成IOC、AOP及Spring的其它功能,获得ApplicationContext的常用方法有两种:
2.1.1、定义一个Service类,BookTypeService代码如下:
package com.zhangguo.Spring61.service; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.zhangguo.Spring61.entities.BookType; import com.zhangguo.Spring61.mapping.BookTypeDAO; /* * 图书类型服务 */ @Service public class BookTypeService { @Resource BookTypeDAO bookTypeDAO; public ListgetAllBookTypes() { System.err.println("一些被省去的业务"); return bookTypeDAO.getAllBookTypes(); } }
@Service表示Spring容器将自动管理BookTypeService实例,@Resource表示自动装配,会自动从Spring容器中找到类型为BookTypeDAO的Bean完成bookTypeDAO字段的初始化。
2.1.2、定义一个Servlet,BookTypeList Servlet代码如下:
package com.zhangguo.Spring61.action; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.zhangguo.Spring61.service.BookTypeService; @WebServlet("/BookTypeList.do") public class BookTypeList extends HttpServlet { private static final long serialVersionUID = 1L; BookTypeService bookTypeService; @Override public void init() throws ServletException { //在当前上下文中获得Spring容器 WebApplicationContext ctx=WebApplicationContextUtils.getWebApplicationContext(getServletContext()); //从容器中获得bean bookTypeService=ctx.getBean(BookTypeService.class); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter writer=response.getWriter(); writer.print(bookTypeService.getAllBookTypes().size()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
在Servlet中我们重写了父类的init方法,注意如果重写带参数的那个init方法init(ServletConfig config),则一定要记得调用父类的init方法完成参数的初始化,即不要删除super.init(config),如果不这样将获不到servlet下上文;在init方法中我们通过WebApplicationContextUtils类获得得了Spring容器。
此时的applicationContext.xml文件如下:
View Code
运行结果: