源码日记--spring 第一篇

来源:互联网 发布:mac上类似sai的软件 编辑:程序博客网 时间:2024/06/06 17:05

在web中使用spring  第一步是使用ContextLoaderListener在web.xml中配置。它是一个listener 集成org.springframework.web.context.ContextLoader和实现接口javax.servlet.ServletContextListener。核心是实现了接口的两个方法,在web容器启动时候初始化listener的时候会触发所有在web.xml中注册的实现或间接实现.ServletContextListener的类的contextInitialized(ServletContextEvent event)和在容器关闭的时候触发所有实现或间接实现ServletContextListener的类的contextDestroyed(ServletContextEvent event)方法。spring也不例外,相比较而言,struts2是采用的过滤器filter实现的与web集成(这么比较一下,可能会更容易让人记得住),

开始分析:

     一。 contextInitalized(ServletContextEvent event) {       initWebApplicationContext(event.getServletContext());}

    二。 initWebApplicationContext(event.getServletContext());根据系统上下文(event.getServletContext()返回Servlet)初始化webApplicationContext  

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {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!");}Log logger = LogFactory.getLog(ContextLoader.class);servletContext.log("Initializing Spring root WebApplicationContext");if (logger.isInfoEnabled()) {logger.info("Root WebApplicationContext: initialization started");}long startTime = System.currentTimeMillis();try {// Store context in local instance variable, to guarantee that// it is available on ServletContext shutdown.if (this.context == null) {      //核心方法①,创建一个新的webApplicationContext对象                              this.context = createWebApplicationContext(servletContext);}if (this.context instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;if (!cwac.isActive()) {// The context has not yet been refreshed -> provide services such as// setting the parent context, setting the application context id, etcif (cwac.getParent() == null) {// The context instance was injected without an explicit parent ->// determine parent for root web application context, if any.ApplicationContext parent = loadParentContext(servletContext);cwac.setParent(parent);}configureAndRefreshWebApplicationContext(cwac, servletContext);}}servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);ClassLoader ccl = Thread.currentThread().getContextClassLoader();if (ccl == ContextLoader.class.getClassLoader()) {currentContext = this.context;}else if (ccl != null) {currentContextPerThread.put(ccl, this.context);}if (logger.isDebugEnabled()) {logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");}if (logger.isInfoEnabled()) {long elapsedTime = System.currentTimeMillis() - startTime;logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");}return this.context;}catch (RuntimeException ex) {logger.error("Context initialization failed", ex);servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);throw ex;}catch (Error err) {logger.error("Context initialization failed", err);servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);throw err;}}

①createWebApplicationContext(servletContext);是.ContextLoader中的一个一个方法:
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {Class<?> contextClass = determineContextClass(sc);if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {throw new ApplicationContextException("Custom context class [" + contextClass.getName() +"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");}return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);}

利用生成工具类生成了一个WebApplicationContext实例,WebApplicationContext集成ApplicationContext

ApplicationContext接口集成EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver等接口,暂时还不知这些接口的定义是什么。现在回头看生成的WebApplicationContext(实际上是一个ConfigurableWebApplicationContext实例)。