spring framework 源码分析,从入口开始

本文结合上一篇编译spring的源码和单元测试以及spring官方文档,从细节入手,学习spring frmaework的使用方法以及实现原理,另一个目的:学会如何查看开源项目源码


首先从spring入口开始,spring编译好的源码中找到/spring-webmvc/src/test/resources/org/springframework/web/context/WEB-INF/web.xml文件,为什么先找这个文件?(Web.xml详解 ),



    config
    org.springframework.framework.web.context.ContextLoaderServlet
    
        contextClass
        org.springframework.framework.web.context.XMLWebApplicationContext       
    
    
        log4jPropertiesUrl
        /WEB-INF/log4j_PRODUCTION.properties     
    
    
    1
  

可以看到首先加载org.springframework.framework.web.context.ContextLoaderServlet文件,再eclipse 中Ctrl+Shift+R,搜索此文件,竟然没找到,出师不利呀.

百度“找不到ContextLoaderServlet”,提示因在Spring3.0中去掉了ContextLoaderServletLog4jConfigServlet,所以会出现找不到类的异常错误。Spring3.0下可以采用另外两种启动方式:ContextLoaderListenerContextLoaderPlugIn。建议使用ContextLoaderListener。于是查找ContextLoaderListener文件,这个总算是有,不明白为什么源码和配置文件不匹配呢?然后网上找了一个使用ContextLoaderListener的配置web.xml 。

  
  
  
  
    org.springframework.web.context.ContextLoaderListener  
  
  
  
  
    contextConfigLocation  
    classpath:spring/applicationContext.xml  
  

1.如果在web.xml中不写任何参数配置信息,默认的路径是"/WEB-INF/applicationContext.xml, 在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml
2.如果是要自定义文件名可以在web.xml里加入contextConfigLocation这个context参数
带着问题看源码,1. 默认路径如何指定?2. 自定义文件名如何实现的?
打开ContextLoaderListener.java 文件。

  /**
    * Initialize the root web application context.
    */
   @Override
   public void contextInitialized(ServletContextEvent event) {
       initWebApplicationContext(event.getServletContext());
   }```
进入`initWebApplicationContext `方法
![initWebApplicationContext
](http://upload-images.jianshu.io/upload_images/2783430-03bac226391c8edd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
此方法中设置自定义配置文件,如果没指定,通过refresh()方法调用默认路径
1. 默认路径如何指定?
![determineContextClass](http://upload-images.jianshu.io/upload_images/2783430-40b26f2ecf3f98fd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
未指定contextClassName时,从defaultStrategies取默认className
![defaultStrategies](http://upload-images.jianshu.io/upload_images/2783430-c6a76bdf1aa6ba23.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![ContexLoad.properties](http://upload-images.jianshu.io/upload_images/2783430-5d127fa0716c8980.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
wac 返回默认的XmlWebApplicationContext实例。
![configureAndRefreshWebApplicationContext](http://upload-images.jianshu.io/upload_images/2783430-6f6ea554f3cffd60.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
查找`XmlWebApplicationContext`的`refresh()`方法,该类中未找到,一直往上层父类中寻找,最终`AbstractApplicationContext`中找到。
![refresh_getDefaultConfigLocations](http://upload-images.jianshu.io/upload_images/2783430-5121dfe1a51ac594.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
`refresh()` 一级级调用直到`XmlWebApplicationContext`的`getDefaultConfigLoactions()`方法
![getDefaultConfigLocations](http://upload-images.jianshu.io/upload_images/2783430-e02c18babd6f24dd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
返回默认的配置文件地址
2. 自定义文件名如何实现的?
`public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";`
![configureAndRefreshWebApplicationContext](http://upload-images.jianshu.io/upload_images/2783430-6f6ea554f3cffd60.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
检查contextConfigLocation参数是否指定?如果有,wac.setConfigLocation()添加自定义配置文件。
![getConfigLocations](http://upload-images.jianshu.io/upload_images/2783430-2d7f0d8462d02e4f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
如果已经指定自定义文件了,就不再使用默认位置。之前跟到这个地方发现`getDefaultConfigLocation()` 返回`null`,并未返回defaultContextLoaction。后来想明白是因为wac 是`XmlWebApplicationContext`实例,也应该调用`XmlWebApplicationContext`的`getDefaultConfigLocation()`方法,而不是此处父类方法。

你可能感兴趣的:(spring framework 源码分析,从入口开始)