Spring源码分析

在Java EE项目中,Spring的载入时通过监听器实现的,无论是在SSH还是SSM,在web.xml都会有这样的配置

	<!-- 载入spring配置 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:cn/resources/applicationContext.xml
        </param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
进入ContextLoaderListener这个类

 public class ContextLoaderListener
/*     */   extends ContextLoader
/*     */   implements ServletContextListener
/*     */ {
/*     */   public ContextLoaderListener() {}
/*     */   
/*     */   public ContextLoaderListener(WebApplicationContext context)
/*     */   {
/*  98 */     super(context);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void contextInitialized(ServletContextEvent event)
/*     */   {
/* 107 */     initWebApplicationContext(event.getServletContext());
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void contextDestroyed(ServletContextEvent event)
/*     */   {
/* 116 */     closeWebApplicationContext(event.getServletContext());
/* 117 */     ContextCleanupListener.cleanupAttributes(event.getServletContext());
/*     */   }
/*     */ }

contextInitialized与contextDestroyed分别对应着初始化与销毁,我们来看看初始化

public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
/*     */   {
/* 296 */     if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
/* 297 */       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!");
/*     */     }
/*     */     
/*     */ 
/*     */ 
/* 302 */     Log logger = LogFactory.getLog(ContextLoader.class);
/* 303 */     servletContext.log("Initializing Spring root WebApplicationContext");
/* 304 */     if (logger.isInfoEnabled()) {
/* 305 */       logger.info("Root WebApplicationContext: initialization started");
/*     */     }
/* 307 */     long startTime = System.currentTimeMillis();
/*     */     
/*     */ 
/*     */     try
/*     */     {
/* 312 */       if (this.context == null) {
/* 313 */         this.context = createWebApplicationContext(servletContext);
/*     */       }
/* 315 */       if ((this.context instanceof ConfigurableWebApplicationContext)) {
/* 316 */         ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context;
/* 317 */         if (!cwac.isActive())
/*     */         {
/*     */ 
/* 320 */           if (cwac.getParent() == null)
/*     */           {
/*     */ 
/* 323 */             ApplicationContext parent = loadParentContext(servletContext);
/* 324 */             cwac.setParent(parent);
/*     */           }
/* 326 */           configureAndRefreshWebApplicationContext(cwac, servletContext);
/*     */         }
/*     */       }
/* 329 */       servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
/*     */       
/* 331 */       ClassLoader ccl = Thread.currentThread().getContextClassLoader();
/* 332 */       if (ccl == ContextLoader.class.getClassLoader()) {
/* 333 */         currentContext = this.context;
/*     */       }
/* 335 */       else if (ccl != null) {
/* 336 */         currentContextPerThread.put(ccl, this.context);
/*     */       }
/*     */       
/* 339 */       if (logger.isDebugEnabled()) {
/* 340 */         logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
/*     */       }
/*     */       
/* 343 */       if (logger.isInfoEnabled()) {
/* 344 */         long elapsedTime = System.currentTimeMillis() - startTime;
/* 345 */         logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
/*     */       }
/*     */       
/* 348 */       return this.context;
/*     */     }
/*     */     catch (RuntimeException ex) {
/* 351 */       logger.error("Context initialization failed", ex);
/* 352 */       servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
/* 353 */       throw ex;
/*     */     }
/*     */     catch (Error err) {
/* 356 */       logger.error("Context initialization failed", err);
/* 357 */       servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
/* 358 */       throw err;
/*     */     }
/*     */   }




Spring 源码分析是一个相对复杂和庞大的话题,无法在一次对话中详细讨论。不过,我可以给你提供一些关于 Spring 源码分析的一般指导和建议。 1. 了解 Spring 的核心模块:Spring 框架是模块化的,每个模块都有不同的功能和职责。在开始源码分析之前,你需要先了解 Spring 的核心模块,如 Spring Core、Spring MVC、Spring Data 等。 2. 阅读官方文档和源码注释:Spring 框架的官方文档和源码注释是你学习和理解源码的重要资源。官方文档提供了对 Spring 各个模块的详细说明,源码注释则解释了代码的作用和实现细节。 3. 调试和跟踪代码:在进行源码分析时,调试器是你的好帮手。通过设置断点、单步跟踪以及观察变量的值,你可以深入理解代码的执行流程和逻辑。 4. 理解设计模式和原理:Spring 框架采用了许多设计模式和原理来实现其功能。在分析源码时,你需要熟悉这些设计模式和原理,例如依赖注入、AOP、工厂模式等。 5. 参考开源社区和博客:Spring 框架是一个非常活跃的开源社区,许多开发者在博客和论坛上分享了他们的源码分析和理解。阅读这些文章可以帮助你更好地理解 Spring 框架的实现细节。 请记住,深入分析 Spring 源码需要耐心和时间投入,同时也需要有一定的 Java 和设计模式的基础。希望这些指导对你有所帮助!如果你有具体的问题或者需要更详细的信息,欢迎继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值