前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >详解contextConfigLocation

详解contextConfigLocation

作者头像
全栈程序员站长
发布2022-09-14 10:37:36
4000
发布2022-09-14 10:37:36
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

spring的应用初始化流程一直没有搞明白,刚刚又碰到了相关的问题。决定得好好看看这个流程。我们在开发spring的项目当中基本上都会在web.xml通过:

代码语言:javascript
复制
<context-param>          <param-name>contextConfigLocation</param-name>          <param-value>          /WEB-INF/conf/application-*.xml          </param-value>      </context-param>  

来初始化各个spring的配置文件,但是我们只是知道这段代码的功能, 并不是很清楚我们配置了这段代码之后为什么就能去初始化配置文件。当然我们还会加上:

代码语言:javascript
复制
<listener>          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>      </listener> 

这一个listener,我首先就会想contextConfigLocation这个一定能在ContextLoaderListener这个类当中找到,打开了源码,这个listener是实现了ServletContextListener这个接口的,这个接口只有两个方法:

而且它是继承了EventListener这个接口的,打开这个接口的代码让我大吃一惊,里面没有方法啥都没有:

而且还是java.util包下的,并不是spring之中的东西。

这样找了之后没有找到,往回退到ContextLoaderListener这个类的方法上,contextInitialized方法是用来初始化上下文的:

方法中有个createContextLoader方法:

这个方法返回了一个ContextLoader实例,进入到ContextLoader类中,按ctrl+f来寻找contextConfigLocation,这时没有出现电脑的咚的声音,找到了它:

通过代码,ConfigurableWebApplicationContext设置了从servletContext获取到的参数的值,再进入ConfigurableWebApplicationContext的代码中,它只是一个接口,进入StaticWebApplicationContext的setConfigLocation方法: view plain copy print ?

这个方法中很奇怪,当参数不为空就抛出异常,查看spring的文档: The StaticWebApplicationContext class does not support this method.说是此类不支持这个方法,这下子又卡住了。又要退回去,看这句:

代码语言:javascript
复制
ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass)

spring使用BeanUtils来初始化contextClass这个类实例,contextClass是通过以下代码得到的:

这里使用了反射,再来看BeanUtils的instantiateClass方法:

代码语言:javascript
复制
return instantiateClass(clazz.getDeclaredConstructor((Class[])null), null);  

通过反射得到contextClass的构造方法。下面是instantiateClass方法的重载,主要是下面两句代码:

代码语言:javascript
复制
ReflectionUtils.makeAccessible(ctor);  
            return ctor.newInstance(args);  

ctor是通过反射得到的contextClass的构造方法,args是构造方法当中的参数。这里为null,说明new了contextClass的无参构造方法。

这时又要退回到determineContextClass 这个方法中,我们主要看:

[html] view plain copy print ?

  1. contextClassName = defaultStrategies.getProperty((org.springframework.web.context.WebApplicationContext.class).getName());

这句代码,我们可以猜它是通过Properties的getProperty方法得到 WebApplicationContext 的实例,这时我们又到了WebApplicationContext 这个接口当中,这个接口继承了ApplicationContext这个接口,我们都知道我们进行spring开发都会通过Application ctx=new FileSystemXmlApplicationContext(“beans.xml”);或ApplicationContext ctx=new ClassPathXmlApplicationContext(“beans.xml”);或ServletContext servletContext = request.getSession().getServletContext();ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);这三种方法获得一个ApplicationContext,然后就可以对配置文件当中的bean进行操作了。所以这里我们基本上已经搞清楚初始化spring配置文件的流程了。

总结:通过查看这几个类的源代码,java的反射使用范围之广再次体现出来。如看了之后觉得有错误或者不同意见,欢迎提出来,我也是第一次才研究这个问题。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/158024.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年7月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档