初探spring applicationContext在web容器中加载过程 首先从WEB.XML入手 ==>web.xml(1)

初探spring applicationContext在web容器中加载过程 首先从WEB.XML入手 ==>web.xml(1)



[java]  view plain copy
  1. <context-param>  
  2. <param-name>webAppRootKey</param-name>  
  3. <param-value>task.root</param-value>  
  4. </context-param>  
  5. <!-- 定义SPRING配置文件 -->  
  6.   
  7. <context-param>  
  8. <param-name>contextConfigLocation</param-name>  
  9. <param-value>/WEB-INF/taskContext*.xml</param-value>  
  10. </context-param>  
  11.   
  12. <context-param>  
  13. <param-name>log4jConfigLocation</param-name>  
  14. <param-value>/WEB-INF/log4j.properties</param-value>  
  15. </context-param>  
  16. <!-- 定义LOG4J监听器 -->  
  17. <listener>  
  18. <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
  19. </listener>  
  20.    
  21. <!-- 定义SPRING监听器 -->  
  22.   
  23. <listener>  
  24. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  25. </listener>  
  26. 进入contextLoaderListener看看到底加载时做了甚么 ==>org.springframework.web.context.ContextLoaderListener   
  27.   
  28.   
  29. public class ContextLoaderListener implements ServletContextListener {  
  30.    
  31. private ContextLoader contextLoader;  
  32.    
  33. /** 
  34. * Initialize the root web application context. 
  35. */  
  36. //当WEB上下文初始化时,系统会调用此方法  
  37. public void contextInitialized(ServletContextEvent event) {  
  38. this.contextLoader = createContextLoader();  
  39.    
  40.   
  41. //监听到WEB上下文初始化的时候执行SPRING上下文contextLoader的初始化工作  
  42. this.contextLoader.initWebApplicationContext(event.getServletContext());  
  43.   
  44. }  
  45.    
  46. /** 
  47. * Create the ContextLoader to use. Can be overridden in subclasses. 
  48. * @return the new ContextLoader 
  49. */  
  50. protected ContextLoader createContextLoader() {  
  51. return new ContextLoader();  
  52. }  
  53.    
  54. /** 
  55. * Return the ContextLoader used by this listener. 
  56. */  
  57. public ContextLoader getContextLoader() {  
  58. return contextLoader;  
  59. }  
  60.    
  61. /** 
  62. * Close the root web application context. 
  63. */  
  64. public void contextDestroyed(ServletContextEvent event) {  
  65. if (this.contextLoader != null) {  
  66. this.contextLoader.closeWebApplicationContext(event.getServletContext());  
  67. }  
  68. }  
  69.    
  70. } 看一下是怎么来初始化webapplicationContext的 ==>contextLoader.initWebApplicationContext   
  71.   
  72. public WebApplicationContext initWebApplicationContext(ServletContext servletContext)  
  73. throws IllegalStateException, BeansException {  
  74.    
  75. if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {  
  76. throw new IllegalStateException(  
  77. "Cannot initialize context because there is already a root application context   
  78.    
  79. present - " +  
  80. "check whether you have multiple ContextLoader* definitions in your web.xml!");  
  81. }  
  82.    
  83. long startTime = System.currentTimeMillis();  
  84. if (logger.isInfoEnabled()) {  
  85. logger.info("Root WebApplicationContext: initialization started");  
  86. }  
  87. servletContext.log("Loading Spring root WebApplicationContext");  
  88.    
  89. try {  
  90. // Determine parent for root web application context, if any.  
  91. ApplicationContext parent = loadParentContext(servletContext);  
  92.    
  93. // Store context in local instance variable, to guarantee that  
  94. // it is available on ServletContext shutdown.  
  95.    
  96.   
  97. //创建web上下文  
  98. this.context = createWebApplicationContext(servletContext, parent);  
  99. servletContext.setAttribute(  
  100. WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);  
  101.   
  102.    
  103. if (logger.isInfoEnabled()) {  
  104. logger.info("Using context class [" + this.context.getClass().getName() +  
  105. "] for root WebApplicationContext");  
  106. }  
  107. if (logger.isDebugEnabled()) {  
  108. logger.debug("Published root WebApplicationContext [" + this.context +  
  109. "] as ServletContext attribute with name [" +  
  110. WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");  
  111. }  
  112. if (logger.isInfoEnabled()) {  
  113. long elapsedTime = System.currentTimeMillis() - startTime;  
  114. logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + "   
  115.    
  116. ms");  
  117. }  
  118.    
  119. return this.context;  
  120. }  
  121. catch (RuntimeException ex) {  
  122. logger.error("Context initialization failed", ex);  
  123. servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);  
  124. throw ex;  
  125. }  
  126. catch (Error err) {  
  127. logger.error("Context initialization failed", err);  
  128. servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);  
  129. throw err;  
  130. }  
  131. } ==>contextLoader.createWebApplicationContext(servletContext, parent);   
  132.   
  133. protected WebApplicationContext createWebApplicationContext(  
  134. ServletContext servletContext, ApplicationContext parent) throws BeansException {  
  135.   
  136. //根据servletContext来决定要实例化的WebApplicationContext  
  137. Class contextClass = determineContextClass(servletContext);  
  138. if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {  
  139. throw new ApplicationContextException("Custom context class [" + contextClass.getName() +  
  140. "] is not of type ConfigurableWebApplicationContext");  
  141. }  
  142. ConfigurableWebApplicationContext wac =  
  143. (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);  
  144. wac.setParent(parent);  
  145. wac.setServletContext(servletContext);  
  146.    
  147. //得到WEB.XML中设置的SPRING配置文件位置  
  148. String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);  
  149. if (configLocation != null) {  
  150. //把配置文件分段后设置到WebApplicationContext的ConfigLocations中  
  151. wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,  
  152. ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));  
  153. }  
  154. //刷新WebApplicationContext  
  155. wac.refresh();  
  156.   
  157. return wac;  
  158. } ==>contextLoader.determineContextClass(servletContext);   
  159.   
  160. protected Class determineContextClass(ServletContext servletContext) throws ApplicationContextException {  
  161.   
  162. //获得需要实例化的CONTEXT类名,在web.xml中有设置,如果没有设置,那么为空  
  163. String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);  
  164. if (contextClassName != null) {  
  165. try {  
  166. return ClassUtils.forName(contextClassName);  
  167. }  
  168. catch (ClassNotFoundException ex) {  
  169. throw new ApplicationContextException(  
  170. "Failed to load custom context class [" + contextClassName + "]", ex);  
  171. }  
  172. }  
  173. //如果在spring web.xml中没有设置context类位置,那么取得默认context  
  174. else {  
  175. //取得defaultStrategies配置文件中的WebApplicationContext属性  
  176. contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());  
  177. try {  
  178. return ClassUtils.forName(contextClassName);  
  179. }  
  180. catch (ClassNotFoundException ex) {  
  181. throw new ApplicationContextException(  
  182. "Failed to load default context class [" + contextClassName + "]", ex);  
  183. }  
  184. }  
  185.   
  186. } SPRING上下文默认的策略是甚么呢? ==>contextLoader.defaultStrategies   
  187.   
  188. private static final Properties defaultStrategies;  
  189.    
  190. static {  
  191. // Load default strategy implementations from properties file.  
  192. // This is currently strictly internal and not meant to be customized  
  193. // by application developers.  
  194. try {  
  195.   
  196. //设置classpath为contextLoader同级目录  
  197. ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);  
  198. //加载该目录下的所有properties文件  
  199. defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);  
  200.   
  201. }  
  202. catch (IOException ex) {  
  203. throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());  
  204. }  
  205. } 找到同级目录下的配置文件 ==>ContextLoader.properties   
  206.   
  207. # Default WebApplicationContext implementation class for ContextLoader.  
  208. # Used as fallback when no explicit context implementation has been specified as context-param.  
  209. # Not meant to be customized by application developers.  
  210.    
  211.   
  212. #默认的WebApplicationContext为org.springframework.web.context.support.XmlWebApplicationContext  
  213. org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext  
  214. ==>org.springframework.web.context.support.XmlWebApplicationContext   
  215.   
  216. public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {  
  217.    
  218. /** Default config location for the root context */  
  219.    
  220.   
  221. //配置了默认的spring配置文件  
  222. public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";  
  223.   
  224.    
  225. //配置文件默认BUILD路径  
  226. public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";  
  227.    
  228. //配置文件默认后缀名  
  229. public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";  
  230.    
  231. /** 
  232. * Loads the bean definitions via an XmlBeanDefinitionReader. 
  233. * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader 
  234. * @see #initBeanDefinitionReader 
  235. * @see #loadBeanDefinitions 
  236. */  
  237. //获得bean配置  
  238. protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {  
  239. //从BEAN工厂获得一个XmlBeanDefinitionReader 来读取SPRING配置文件  
  240. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);  
  241.    
  242. //设置beanDefinitionReader服务于当前CONTEXT  
  243. // resource loading environment.  
  244. beanDefinitionReader.setResourceLoader(this);  
  245. beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));  
  246.    
  247. // Allow a subclass to provide custom initialization of the reader,  
  248. // then proceed with actually loading the bean definitions.  
  249. initBeanDefinitionReader(beanDefinitionReader);  
  250.   
  251. //读取配置文件  
  252. loadBeanDefinitions(beanDefinitionReader);  
  253.   
  254. }  
  255.    
  256. /** 
  257. * Initialize the bean definition reader used for loading the bean 
  258. * definitions of this context. Default implementation is empty. 
  259. * <p>Can be overridden in subclasses, e.g. for turning off XML validation 
  260. * or using a different XmlBeanDefinitionParser implementation. 
  261. * @param beanDefinitionReader the bean definition reader used by this context 
  262. * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setValidationMode 
  263. * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass 
  264. */  
  265. protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {  
  266. }  
  267.    
  268. /** 
  269. * Load the bean definitions with the given XmlBeanDefinitionReader. 
  270. * <p>The lifecycle of the bean factory is handled by the refreshBeanFactory method; 
  271. * therefore this method is just supposed to load and/or register bean definitions. 
  272. * <p>Delegates to a ResourcePatternResolver for resolving location patterns 
  273. * into Resource instances. 
  274. * @throws org.springframework.beans.BeansException in case of bean registration errors 
  275. * @throws java.io.IOException if the required XML document isn't found 
  276. * @see #refreshBeanFactory 
  277. * @see #getConfigLocations 
  278. * @see #getResources 
  279. * @see #getResourcePatternResolver 
  280. */  
  281.   
  282. //读取配置文件  
  283. protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {  
  284. String[] configLocations = getConfigLocations();  
  285. if (configLocations != null) {  
  286. for (int i = 0; i < configLocations.length; i++) {  
  287. reader.loadBeanDefinitions(configLocations[i]);  
  288. }  
  289. }  
  290. }  
  291.   
  292.    
  293. /** 
  294. * The default location for the root context is "/WEB-INF/applicationContext.xml", 
  295. * and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet" 
  296. * (like for a DispatcherServlet instance with the servlet-name "test"). 
  297. */  
  298. //获得默认的ConfigLocations  
  299. protected String[] getDefaultConfigLocations() {  
  300. if (getNamespace() != null) {  
  301. return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() +   
  302.    
  303. DEFAULT_CONFIG_LOCATION_SUFFIX};  
  304. }  
  305. else {  
  306. return new String[] {DEFAULT_CONFIG_LOCATION};  
  307. }  
  308. }   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值