Spring Framework及SpringMVC源码阅读1

  • web应用的启动过程

    熟悉的web应用都带有一个web.xml配置文件,web应用的启动就是从这个web.xml开始的。web应用放入servlet容器如tomcat中,tomcat启动时加载web.xml。web.xml中有四个常用的配置项:

    • listener 经常被叫做监听器
    • context-param
    • filter 经常被叫做过滤器
    • servlet servlet将接收到的http请求交给对应的servlet处理

    启动过程时这样的:

    • 首先创建web.xml中配置的监听器,监听容器中发生的事件。
    <listener>
    	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    • 然后创建一个servletContext,将context-param中配置的参数放入其中,该servletContext在该应用中所有对象共享。
    <context-param>
    	<param-name>contextConfigLocation</param-name>
    	<param-value>
    		/WEB-INF/spring-mybatis.xml,/WEB-INF/spring-security.xml,/WEB-INF/spring-redis.xml,/WEB-INF/spring-quartz-cluster.xml,/WEB-INF/application-dictionary.xml,/WEB-INF/application-mail.xml,/WEB-INF/activeMq.xml
    	</param-value>
    </context-param>
    
    • 这时监听器监听到servletContext的创建事件后,进行对应的初始化操作:
    void org.springframework.web.context.ContextLoaderListener.contextInitialized(ServletContextEvent event)
    /**
     * Initialize the root web application context.
     */
    @Override
    public void contextInitialized(ServletContextEvent event) {
    	initWebApplicationContext(event.getServletContext());
    }
    
    • 创建过滤器filter
    • 创建Servlet并初始化Servlet
    • 启动完成,监听服务器端口接收http请求。
  1. SpringFramework的初始化

    从启动过程可以看到,springframework利用一个监听器ContextLoaderListener触发初始化。当监听到servletContext创建完成之后,就会进行webApplicationContext的初始化过程,而webApplicationContext初始化完成之后就会把它放入servletContext中,设置为根上下文org.springframework.web.context.WebApplicationContext.root

    	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) {
    			this.context = createWebApplicationContext(servletContext);//新建一个WebApplicationContext,实际上就是调用一个WebApplicationContext子类的构造器新建一个对象,如果没有在web.xml中制定contextClass,新建一个org.springframework.web.context.support.XmlWebApplicationContext对象
    		}
    		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, etc
    				if (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);//根applicationContext的parent为null
    				}
    				configureAndRefreshWebApplicationContext(cwac, servletContext);
    			}
    		}
    		//把已经初始化的根ApplicationContext作为servletContext的一个属性
    		servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
    

    rootApplicationContext的初始化过程在configureAndRefreshWebApplicationContext方法中完成。下面看下rootApplicationContext的初始化过程。

posted @ 2018-06-22 09:12  尿布维护工程师  阅读(233)  评论(0)    收藏  举报