现在的位置: 首页 > 综合 > 正文

spring在于tomcat的整合原理

2019年05月26日 ⁄ 综合 ⁄ 共 11451字 ⁄ 字号 评论关闭

这篇文章主要是源码的一个整理:将来要是忘了可以看看:

这是spring的启动listener:

/*** Eclipse Class Decompiler plugin, copyright (c) 2012 Chao Chen (cnfree2000@hotmail.com) ***/
package org.springframework.web.context;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextLoaderListener extends ContextLoader implements
		ServletContextListener {
	private ContextLoader contextLoader;

	public ContextLoaderListener() {
	}

	public ContextLoaderListener(WebApplicationContext context) {
		super(context);
	}

	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			this.contextLoader = this;
		}
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

	@Deprecated
	protected ContextLoader createContextLoader() {
		return null;
	}

	@Deprecated
	public ContextLoader getContextLoader() {
		return this.contextLoader;
	}

	public void contextDestroyed(ServletContextEvent event) {
		if (this.contextLoader != null) {
			this.contextLoader.closeWebApplicationContext(event
					.getServletContext());
		}
		ContextCleanupListener.cleanupAttributes(event.getServletContext());
	}
}

这是初始化方法

/*** Eclipse Class Decompiler plugin, copyright (c) 2012 Chao Chen (cnfree2000@hotmail.com) ***/
package org.springframework.web.context;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class ContextLoader {
	public static final String CONTEXT_CLASS_PARAM = "contextClass";
	public static final String CONTEXT_ID_PARAM = "contextId";
	public static final String CONTEXT_INITIALIZER_CLASSES_PARAM = "contextInitializerClasses";
	public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
	public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
	public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
	private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";
	private static final Properties defaultStrategies;
	private static final Map<ClassLoader, WebApplicationContext> currentContextPerThread;
	private static volatile WebApplicationContext currentContext;
	private WebApplicationContext context;
	private BeanFactoryReference parentContextRef;

	static {
		try {
			ClassPathResource resource = new ClassPathResource(
					"ContextLoader.properties", ContextLoader.class);
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		} catch (IOException ex) {
			throw new IllegalStateException(
					"Could not load 'ContextLoader.properties': "
							+ ex.getMessage());
		}

		currentContextPerThread = new ConcurrentHashMap(1);
	}

	public ContextLoader() {
	}

	public ContextLoader(WebApplicationContext context) {
		this.context = context;
	}

	<span style="color:#ff0000;">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 {
			if (this.context == null) {
				this.context = createWebApplicationContext(servletContext);
			}
			if (this.context instanceof ConfigurableWebApplicationContext) {
				configureAndRefreshWebApplicationContext(
						(ConfigurableWebApplicationContext) this.context,
						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.<span style="background-color: rgb(192, 192, 192);">ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE</span>
						+ "]");
			}
			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;
		}
	}
</span>
	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() + "]");
		}
		ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils
				.instantiateClass(contextClass);
		return wac;
	}

	@Deprecated
	protected WebApplicationContext createWebApplicationContext(
			ServletContext sc, ApplicationContext parent) {
		return createWebApplicationContext(sc);
	}

	protected void configureAndRefreshWebApplicationContext(
			ConfigurableWebApplicationContext wac, ServletContext sc) {
		if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
			String idParam = sc.getInitParameter("contextId");
			if (idParam != null) {
				wac.setId(idParam);
			} else if ((sc.getMajorVersion() == 2)
					&& (sc.getMinorVersion() < 5)) {
				wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX
						+ ObjectUtils.getDisplayString(sc
								.getServletContextName()));
			} else {
				wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX
						+ ObjectUtils.getDisplayString(sc.getContextPath()));
			}

		}

		ApplicationContext parent = loadParentContext(sc);

		wac.setParent(parent);
		wac.setServletContext(sc);
		String initParameter = sc.getInitParameter("contextConfigLocation");
		if (initParameter != null) {
			wac.setConfigLocation(initParameter);
		}
		customizeContext(sc, wac);
		wac.refresh();
	}

	protected Class<?> determineContextClass(ServletContext servletContext) {
		String contextClassName = servletContext
				.getInitParameter("contextClass");
		if (contextClassName != null) {
			try {
				return ClassUtils.forName(contextClassName,
						ClassUtils.getDefaultClassLoader());
			} catch (ClassNotFoundException ex) {
				throw new ApplicationContextException(
						"Failed to load custom context class ["
								+ contextClassName + "]", ex);
			}
		}

		contextClassName = defaultStrategies
				.getProperty(WebApplicationContext.class.getName());
		try {
			return ClassUtils.forName(contextClassName,
					ContextLoader.class.getClassLoader());
		} catch (ClassNotFoundException ex) {
			throw new ApplicationContextException(
					"Failed to load default context class [" + contextClassName
							+ "]", ex);
		}
	}

	protected List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> determineContextInitializerClasses(
			ServletContext servletContext) {
		String classNames = servletContext
				.getInitParameter("contextInitializerClasses");
		List classes = new ArrayList();
		if (classNames != null) {
			for (String className : StringUtils.tokenizeToStringArray(
					classNames, ",")) {
				try {
					Class clazz = ClassUtils.forName(className,
							ClassUtils.getDefaultClassLoader());
					Assert.isAssignable(
							ApplicationContextInitializer.class,
							clazz,
							"class ["
									+ className
									+ "] must implement ApplicationContextInitializer");
					classes.add(clazz);
				} catch (ClassNotFoundException ex) {
					throw new ApplicationContextException(
							"Failed to load context initializer class ["
									+ className + "]", ex);
				}
			}
		}
		return classes;
	}

	protected void customizeContext(ServletContext servletContext,
			ConfigurableWebApplicationContext applicationContext) {
		List initializerClasses = determineContextInitializerClasses(servletContext);

		if (initializerClasses.size() == 0) {
			return;
		}

		ArrayList initializerInstances = new ArrayList();

		for (Class initializerClass : initializerClasses) {
			Class contextClass = applicationContext.getClass();
			Class initializerContextClass = GenericTypeResolver
					.resolveTypeArgument(initializerClass,
							ApplicationContextInitializer.class);
			Assert.isAssignable(
					initializerContextClass,
					contextClass,
					String.format(
							"Could not add context initializer [%s] as its generic parameter [%s] is not assignable from the type of application context used by this context loader [%s]",
							new Object[] { initializerClass.getName(),
									initializerContextClass, contextClass }));
			initializerInstances.add((ApplicationContextInitializer) BeanUtils
					.instantiateClass(initializerClass));
		}

		Collections.sort(initializerInstances,
				new AnnotationAwareOrderComparator());

		WebApplicationContextUtils.initServletPropertySources(
				applicationContext.getEnvironment().getPropertySources(),
				servletContext);

		for (ApplicationContextInitializer initializer : initializerInstances)
			initializer.initialize(applicationContext);
	}

	protected ApplicationContext loadParentContext(ServletContext servletContext) {
		ApplicationContext parentContext = null;
		String locatorFactorySelector = servletContext
				.getInitParameter("locatorFactorySelector");
		String parentContextKey = servletContext
				.getInitParameter("parentContextKey");

		if (parentContextKey != null) {
			BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator
					.getInstance(locatorFactorySelector);
			Log logger = LogFactory.getLog(ContextLoader.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Getting parent context definition: using parent context key of '"
						+ parentContextKey + "' with BeanFactoryLocator");
			}
			this.parentContextRef = locator.useBeanFactory(parentContextKey);
			parentContext = (ApplicationContext) this.parentContextRef
					.getFactory();
		}

		return parentContext;
	}

	public void closeWebApplicationContext(ServletContext servletContext) {
    servletContext.log("Closing Spring root WebApplicationContext");
    label34: ClassLoader ccl;
    try {
      if (!(this.context instanceof ConfigurableWebApplicationContext)) break label34;
      ((ConfigurableWebApplicationContext)this.context).close();
    }
    finally
    {
      ClassLoader ccl = Thread.currentThread().getContextClassLoader();
      if (ccl == ContextLoader.class.getClassLoader()) {
        currentContext = null;
      }
      else if (ccl != null) {
        currentContextPerThread.remove(ccl);
      }
      servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
      if (this.parentContextRef != null)
        this.parentContextRef.release();
    }
  }

	public static WebApplicationContext getCurrentWebApplicationContext() {
		ClassLoader ccl = Thread.currentThread().getContextClassLoader();
		if (ccl != null) {
			WebApplicationContext ccpt = (WebApplicationContext) currentContextPerThread
					.get(ccl);
			if (ccpt != null) {
				return ccpt;
			}
		}
		return currentContext;
	}
}

想要跟清楚的了解,把tomcat的listener,fliter弄明白就可以了

抱歉!评论已关闭.