【spring】IOC容器在WEB容器中的启动
2017-06-16 19:14
555 查看
在非web项目中,我们可以通过在main方法中直接创建IOC容器。而在web项目中,IOC容器是如何创建的?IOC
容器是如何在web容器中启动的?这就是本篇博客要阐述的问题,下面我们先从一个实例出发。
【简单实例】
1. 新建一个java web项目,创建web.xml和applicationContext.xml两个配置文件,前者是对web容器的管理
,后者是对spring ioc容器的管理。
2. 新建一个简单的bean,其中包含username属性,hello方法可输出配置的属性名称。
package com.hzt.spring.struts2.beans; public class Person { private String username; public void setUsername(String username) { this.username = username; } public void hello(){ System.out.println("My name is " + username); } }
3. 新建一个监听器SpringServletContextListener,并且实现ServletContextListener接口,实现
contextInitialized()方法,将IOC容器至于ServletContext中。
package com.hzt.spring.struts2.listeners; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Application Lifecycle Listener implementation class SpringServletContextListener * */ public class SpringServletContextListener implements ServletContextListener { /** * Default constructor. */ public SpringServletContextListener() { // TODO Auto-generated constructor stub } /** * @see ServletContextListener#contextInitialized(ServletContextEvent) */ public void contextInitialized(ServletContextEvent arg0) { //1. 获取spring配置文件的名称 ServletContext servletContext = arg0.getServletContext(); String config = servletContext.getInitParameter("configLocation"); //1. 创建IOC容器 ApplicationContext ctx = new ClassPathXmlApplicationContext(config); //2. 把IOC容器放在servletContext的一个属性中 servletContext.setAttribute("ApplicationContext", ctx); } /** * @see ServletContextListener#contextDestroyed(ServletContextEvent) */ public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub } }
4. 新建一个TestServlet,继承HttpServlet,重写其中的doGet()方法,测试是否能从web容器中获取到IOC
容器,并且获取到对应的bean。
package com.hzt.spring.struts2.servlets; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationContext; import com.hzt.spring.struts2.beans.Person; public class TestServlet extends HttpServlet{ /** * */ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 从application域对象中得到IOC容器的引用 ServletContext servletContext = getServletContext(); ApplicationContext ctx=(ApplicationContext) servletContext.getAttribute("ApplicationContext"); //2. 从IOC容器中得到需要的bean Person person=ctx.getBean(Person.class); person.hello(); } }
5. 在web.xml中配置spring的配置文件,并添加上面写好的监听器。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 配置spring配置文件的名称和位置 --> <context-param> <param-name>configLocation</param-name> <param-value>applicationContext.xml</param-value> </context-param> <listener> <listener-class>com.hzt.spring.struts2.listeners.SpringServletContextListener</listener-class> </listener> </web-app>
6. 在applicationContext.xml中配置bean
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <bean id="person" class="com.hzt.spring.struts2.beans.Person"> <property name="username" value="hzt"></property> </bean> </beans>
此实例结果可以在控制台看到输出了hello方法中的信息结果,也就是我们通过一个小例子实现了在Web容器
中去管理IOC容器的。
【过程一览】
上图是:在web容器中启动spring应用程序的过程。
【过程分析】
有了上面的实例基础以及一张过程图,下面我们进一步结合着spring的源码来分析一下整个过程。
1. 对于web应用程序,我们都会在web.xml中配置一个spring监听器,即ContextLoaderListener,如下:
<!-- 配置IOC容器的 SpringServletContextListener --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
此监听器继承ContextLoader,并且实现了ServletContextListener,其中包含四个方法,分别是两个构造函
数(无参和WebApplicationContext参数)、初始化Context和销毁Context.
2. 在初始化方法contextInitialized()中,实际上是通过ContextLoader类中的initWebApplicationContext()去初始
化的。
其中,初始化逻辑大致可归纳为以下几个步骤:
1) 判断是否存在根上下文,若存在,则直接抛异常,已存在根上下文,不可实现初始化。
2) 输出servletContext.log("Initializing Spring root WebApplicationContext");日志信息,则说明当
前不存在根下上文。
3) 如果当前不存在context,则会创建上下文createWebApplicationContext(Servlet Context)
4) 如果当前存在ConfigurableWebApplicationContext的实例,则会去判断其父容器,若存在父容器,则会
直接启动IOC容器configureAndRefreshWebApplicationContext(cwac,servletContext);若父容器为null,则
loadParentContext(ServletContext),并将结果set到子容器中。
5) 最后会给全局的上下文环境设置属性,根上下文和上下文,即
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
this.context);
总结来说,其上述整个过程主要是ContextLoader做的两件事:一是在Web容器中建立双亲IOC容器;
二是生成对应的webApplicationContext并将其初始化。
【上下文相关】
1. 对于一个Web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,也就是
ServletContext,其为spring IOC容器提供宿主环境。
2. contextInitialized()方法被调用时,spring会启动一个上下文,这个上下文被称为根上下文,即
WebApplicationContext.
3. 在web.xml中,我们通常会配置多个Servlet,每个Servlet都会有自己的一个上下文,称为子上下文,它
也保存在Servlet Context中。
4. 父上下文(父容器)和子上下文(子容器)的访问权限:子上下文可以访问父上下文中的bean,但是父
上下文不可以访问子上下文中的bean。
相关文章推荐
- 【Spring源码解析】之IOC容器在Web容器中的启动
- 转:Spring源码分析:IOC容器在web容器中的启动
- spring(2) spring ioc容器在Web容器中的启动
- Spring Ioc(1)——web中spring容器的启动初步
- Spring源代码分析之(二):IOC容器在web容器中的启动
- Spring源代码解析(二):IoC容器在Web容器中的启动
- Spring IoC容器在Web环境中的启动源码阅读
- Spring源代码解析(二):IoC容器在Web容器中的启动
- 对spring web启动时IOC源码研究
- 对spring web启动时IOC源码研究
- apacheFtpServer集成spring由web容器控制启动和关闭
- spring在web容器启动时执行初始化方法
- Spring 在web 容器中的启动过程
- ServletContext与Web应用以及Spring容器启动
- 【Java.Spring.MVC】Spring在Web容器中的启动过程
- IoC容器在Web容器中的启动1
- Spring IOC容器启动核心
- 随web容器启动Java类,调用spring容器中的的bean及其方法
- 对spring web启动时IOC源码研究
- ServletContext与Web应用以及Spring容器启动