Spring在web.xml中进行配置
1.1加载Spring配置文件
我们首先指定我们需要加载的Spring配置文件,在tomcat容器启动后,会寻找项目中的web.xml文件,加载其中的信息,并创建一个ServletContext上下文对象,以后再web应用中可以获得其中的值。
最先加载的就是<context-param>节点,该节点加载我们的Spring配置文件,配置文件中是我们需要往Spring容器中注册的Bean对象配置。有两种加载方式,如果在web.xml中不指定<context-param>,会默认去加载/WEB-INF/下的ApplicationContext.xml。
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/config/application-context.xml /WEB-INF/config/zxw/zxw-context.xml </param-value> </context-param>
1.2配置监听器,触发监听事件
加载完配置文件后,需要配置监听器。
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener>
监听器的作用是监听ServletContext的对象是否创建,web容器一旦启动,就会创建一个ServletContext对象,所以监听器一定会触发,从而执行监听器的contextInitialized方法。方法看Spring源码如下
public class ContextLoaderListener extends ContextLoader implements ServletContextListener { public ContextLoaderListener() { } public ContextLoaderListener(WebApplicationContext context) { super(context); }
//执行的监听器方法 public void contextInitialized(ServletContextEvent event) { this.initWebApplicationContext(event.getServletContext()); } public void contextDestroyed(ServletContextEvent event) { this.closeWebApplicationContext(event.getServletContext()); ContextCleanupListener.cleanupAttributes(event.getServletContext()); } }
监听器执行contextInitialized方法,从该方法的参数我们也能够看出来,触发的事件是ServletContext对象创建了没,然后执行触发事件,也就是执行initWebApplicationContext方法,实际上该方法定义在其父类ContextLoader中,我们看该方法的具体实现如下
1 public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { 2 if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { 3 throw new IllegalStateException("Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!"); 4 } else { 5 Log logger = LogFactory.getLog(ContextLoader.class); 6 servletContext.log("Initializing Spring root WebApplicationContext"); 7 if (logger.isInfoEnabled()) { 8 logger.info("Root WebApplicationContext: initialization started"); 9 } 10 11 long startTime = System.currentTimeMillis(); 12 13 try { 14 if (this.context == null) { 15 this.context = this.createWebApplicationContext(servletContext); 16 } 17 18 if (this.context instanceof ConfigurableWebApplicationContext) { 19 ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context; 20 if (!cwac.isActive()) { 21 if (cwac.getParent() == null) { 22 ApplicationContext parent = this.loadParentContext(servletContext); 23 cwac.setParent(parent); 24 } 25 26 this.configureAndRefreshWebApplicationContext(cwac, servletContext); 27 } 28 } 29 30 servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); 31 ClassLoader ccl = Thread.currentThread().getContextClassLoader(); 32 if (ccl == ContextLoader.class.getClassLoader()) { 33 currentContext = this.context; 34 } else if (ccl != null) { 35 currentContextPerThread.put(ccl, this.context); 36 } 37 38 if (logger.isDebugEnabled()) { 39 logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]"); 40 } 41 42 if (logger.isInfoEnabled()) { 43 long elapsedTime = System.currentTimeMillis() - startTime; 44 logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms"); 45 } 46 47 return this.context; 48 } catch (RuntimeException var8) { 49 logger.error("Context initialization failed", var8); 50 servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var8); 51 throw var8; 52 } catch (Error var9) { 53 logger.error("Context initialization failed", var9); 54 servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var9); 55 throw var9; 56 } 57 } 58 }
该方法返回一个WebApplicationContext对象,WebApplicationContext接口继承ApplicationContext接口,该接口继承BeanFactory接口,由此看来,这几个接口都是Spring容器,用来注册配置文件中的Bean,Spring容器不仅创建了配置文件中的Bean,而且还负责管理
Bean的生命周期,上面的initWebApplicationContext方法返回一个WebApplicationContext对象context,我们可以通过该对象获得我们配置在Bean中的对象。