`

Spring3.0源码学习---IOC(一)

阅读更多

        最近在SVN上下载了Spring3.0的源码学习. 先介绍个人到现在对于Spring中IOC的认识吧.欢迎大家一起讨论,呵呵,别拍砖.

 

     Spring的IOC的实现分为 1. 资源(Resource)定位 2.资源(Resource)载入 3.资源的解析 4.Bean的注册  5.getBean时对象依赖关系的注入.以最通常用的web项目开始

 

      Spring通过web容器启动是通过org.springframework.web.context.ContextLoaderListener来实现的,其代码如下:

其对ContextLoader的继承及对ServletContextListener的实现使用了适配器模式.

现在看看contextLoader中的initWebApplicationContext方法.

//监听器的初始化方法.对web应用的上下文进行初始化
public void contextInitialized(ServletContextEvent event) {
	this.contextLoader = createContextLoader();
	if (this.contextLoader == null) {
		this.contextLoader = this;
	}
	this.contextLoader.initWebApplicationContext (event.getServletContext());
}
 
 
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 {
		// Determine parent for root web application context, if any.
		ApplicationContext parent = loadParentContext(servletContext);

		// Store context in local instance variable, to guarantee that
		// it is available on ServletContext shutdown.
		this.context = createWebApplicationContext(servletContext, parent);
		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;
		}//异常略...
}

 

   对容器的初始化的过程主要是通过  this.context = createWebApplicationContext(servletContext, parent);
  这句完成的..进入createWebApplicationContext方法

 

	protected WebApplicationContext createWebApplicationContext(ServletContext sc, ApplicationContext parent) {
		//得到确定的class对象.determineContextClass中首先在web.xml中查询是否有配置contextclass的上下文.
		//如果有配置,则根据所配置的对象得到其class对象.否则通过在ContextLoader.properties的
		//org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
		//得到XmlWebApplicationContext的class对象
		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为接口.
		//通过反射将对象实例化.如果web.xml中未配置contextclass的话,实际上是XmlWebApplicationContext对象
		ConfigurableWebApplicationContext wac =
				(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);

		// Assign the best possible id value.
		if (sc.getMajorVersion() == 2 && sc.getMinorVersion() < 5) {
			// Servlet <= 2.4: resort to name specified in web.xml, if any.
			String servletContextName = sc.getServletContextName();
			wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
					ObjectUtils.getDisplayString(servletContextName));
		}
		else {
			// Servlet 2.5's getContextPath available!
			try {
				String contextPath = (String) ServletContext.class.getMethod("getContextPath").invoke(sc);
				wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
						ObjectUtils.getDisplayString(contextPath));
			}
			catch (Exception ex) {
				throw new IllegalStateException("Failed to invoke Servlet 2.5 getContextPath method", ex);
			}
		}

		wac.setParent(parent);
		wac.setServletContext(sc);
		wac.setConfigLocation(sc.getInitParameter(CONFIG_LOCATION_PARAM));
		customizeContext(sc, wac);
		//容器初始化的入口
		wac.refresh();
		return wac;
	}

  

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics