1)idea下debug的时候不会报超时错误。
2)eclipse下debug的时候可能会报tomcat启动超时错误:
错误信息:Server apache-tomcat-8.0.33 at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
解决方法:在Servers视图下,双击"Tomcat v8.0 Server at localhost",设置Timeouts中"Start (in seconds):" 即可。
----------------------------------------------------------------------------------------------------------
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);
}
/**
* Initialize the root web application context.
*/
public void contextInitialized(ServletContextEvent event) { //【1】
this.contextLoader = createContextLoader();
if (this.contextLoader == null) {
this.contextLoader = this;
}
this.contextLoader.initWebApplicationContext(event.getServletContext()); //【2】
}
/**
* Close the root web application context.
*/
public void contextDestroyed(ServletContextEvent event) {
if (this.contextLoader != null) {
this.contextLoader.closeWebApplicationContext(event.getServletContext());
}
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
@Deprecated
protected ContextLoader createContextLoader() {
return null;
}
@Deprecated
public ContextLoader getContextLoader() {
return this.contextLoader;
}
}
-----------------------------------
package org.springframework.web.context;
public class ContextLoader {
/**
* 初始化Web应用中的Spring容器。
* 注意:WebApplicationContext是一个接口,故实例化WebApplicationContext时,需要确定一个WebApplicationContext的实现类,默认使用XmlWebApplicationContext作为实现类。
* Initialize Spring's web application context for the given servlet context,
* using the application context provided at construction time, or creating a new one according to the contextClass and context-params.
*
* @param servletContext current servlet context
* @return the new WebApplicationContext
*/
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { //【2】
// 判断当前ServletContext中是否已经存在一个WebApplicationContext。注:WebApplicationContext启动成功后会绑定到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); //【3.1】
}
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);
}
// 构造bean工厂和容器里bean的创建
configureAndRefreshWebApplicationContext(cwac, servletContext); //【3.2】
}
}
// 将WebApplicationContext绑定到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;
}
}
protected WebApplicationContext createWebApplicationContext(ServletContext sc) { //【3.1】
/**
* determineContextClass方法:
* 获取WebApplicationContext的Class类型,如果我们没有在web.xml中自定义WebApplicationContext的类型(contextClass参数), 则使用默认的类型XmlWebApplicationContext
* Return the WebApplicationContext implementation class to use, either the default XmlWebApplicationContext or a custom context class if specified.
*/
Class<?> contextClass = determineContextClass(sc);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() + "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
}
// 初始化WebApplication
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
// The application context id is still set to its original default value
// -> assign a more useful id based on available information
String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
if (idParam != null) {
wac.setId(idParam);
}
else {
// Generate default id...
if (sc.getMajorVersion() == 2 && sc.getMinorVersion() < 5) {
// Servlet <= 2.4: resort to name specified in web.xml, if any.
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(sc.getServletContextName()));
}
else {
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(sc.getContextPath()));
}
}
}
wac.setServletContext(sc);
String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocationParam != null) {
wac.setConfigLocation(configLocationParam);
}
// The wac environment's #initPropertySources will be called in any case when the context
// is refreshed; do it eagerly here to ensure servlet property sources are in place for
// use in any post-processing or initialization that occurs below prior to #refresh
ConfigurableEnvironment env = wac.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
}
customizeContext(sc, wac);
wac.refresh();
}
}
-----------------------------------
package org.springframework.beans;
public abstract class BeanUtils {
/**
* 使用类的无参构造器来实例化一个类
* Instantiate a class using its no-arg constructor.
*
* @param clazz class to instantiate
* @return the new instance
*/
public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException {
Assert.notNull(clazz, "Class must not be null");
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
return instantiateClass(clazz.getDeclaredConstructor());
}
catch (NoSuchMethodException ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
/**
* 使用Constructor对象的newInstance()方法创建一个类的实例并返回。
* Convenience method to instantiate a class using the given constructor.
*
* @param ctor the constructor to instantiate
* @param args the constructor arguments to apply
* @return the new instance
*/
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(), "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(), "Constructor threw exception", ex.getTargetException());
}
}
}
================================================
=========================================================================================================================
Spring源码分析
最新推荐文章于 2022-03-15 18:32:34 发布