Spring IOC中关于configLoaction的那些事

SpringMVC项目中configLoaction

源头:configLocation通常配置在web.xml中的 init-paramcontext-param 标签中。

<servlet>
	<servlet-name>dispatcherServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>xxx</param-value>
	</init-param>
</servlet>
<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>xxx</param-value>
</context-param>
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

使用:init-param 中配置的configLocaion路径会在DispatcherServlet初始化,配置刷新WebApplicationContext时使用到;context-param 中配置的contextConfigLocation路径会在ContextLoaderListener初始化,配置刷新WebApplicationContext时使用到;

1. 设置contextConfigLocation
1.1 ContextLoaderListener:将contextConfigLocation设置到WebApplicationContext

	//类ContextLoaderListener 106行  Listener的初始化方法
	@Override
	public void contextInitialized(ServletContextEvent event) {
		initWebApplicationContext(event.getServletContext());
	}
	//类ContextLoader 294行 
	//初始化WebapplicationContext,该上下文中通常管理驱动应用后端的中间层和数据层的bean
	public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
		...
		configureAndRefreshWebApplicationContext(cwac, servletContext);
		...
	}
	//类ContextLoader 413行 
	//从web容器上下文中取得配置文件所有位置 设置到WebapplicationContext中
	protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
		...
		//从web容器上下文中获取contextConfigLocation的值,即<context-param>标签中<param-name>为contextConfigLocation的值
		String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
		if (configLocationParam != null) {
			//这里wac 默认是XmlWebApplicationContext
			wac.setConfigLocation(configLocationParam);
		}
		...
	}
	//类AbstractRefreshableConfigApplicationContext 67行
	//可以用【,; \t\n】这些分割符配置多路径
	public void setConfigLocation(String location) {
		setConfigLocations(StringUtils.tokenizeToStringArray(location, CONFIG_LOCATION_DELIMITERS));
	}
	
	//类AbstractRefreshableConfigApplicationContext  75行
	//contextConfigLocation的值最终设置到
	//AbstractRefreshableConfigApplicationContext的属性中 String[] configLocations;
	public void setConfigLocations(String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

1.1 DispatcherServlet:将contextConfigLocation设置到FrameworkServlet

	//类HttpServletBean 147行 DispatcherServlet的初始化
	@Override
	public final void init() throws ServletException {
		...
		//从ServletConfig中获取配置参数
		PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
		if (!pvs.isEmpty()) {
				//将this关联到BeanWrapper 
				BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
				ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
				bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
				initBeanWrapper(bw);
				//将pvs中获取的参数设置到this(DispatcherServlet)中
				bw.setPropertyValues(pvs, true);
		...
	}
	//类FrameworkServlet  354行 
	//将contextConfigLocation设置到FrameServlet的属性中
	//该方法被反射调用  BeanWrapperImpl$BeanPropertyHandler.setValue(obj,obj);
	public void setContextConfigLocation(String contextConfigLocation) {
		this.contextConfigLocation = contextConfigLocation;
	}

2. BeanFactory中对contextConfigLocation的使用

	//类AbstractApplicationContext 515行
	//WebApplicationContext上下文刷新方法
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		...
		//创建配置BeanFactory并返回
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		...
	}
	//类AbstractApplicationContext 614行
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//创建并配置BeanFactory
		refreshBeanFactory();
		...
	}
	//类AbstractApplicationContext 614行
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		...
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		beanFactory.setSerializationId(getId());
		customizeBeanFactory(beanFactory);
		//加载Bean定义,这里需要读取配置文件
		//所以会用到contextConfigLocation
		loadBeanDefinitions(beanFactory);
		...
	}
	//类XmlWebApplicationContext 81行
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		...
		loadBeanDefinitions(beanDefinitionReader);
	}
	//类XmlWebApplicationContext 121行
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
		//获取配置文件路径 
		String[] configLocations = getConfigLocations();
		...
	}
	//类AbstractRefreshableWebApplicationContext 137行
	@Override
	public String[] getConfigLocations() {
		return super.getConfigLocations();
	}
	//类AbstractRefreshableConfigApplicationContext 98行
	//这里this.configLocations就是开始时读取web容器上下文中contextConfigLocation
	//设置到WebApplicationContext的值
	//若开始就没有设置,这里使用默认路径
	protected String[] getConfigLocations() {
		return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
	}
	
	//类XmlWebApplicationContext 136行
	//默认 /WEB-INF/applicationContext.xml 或 
	// /WEB-INF/ + namespace + .xml
	@Override
	protected String[] getDefaultConfigLocations() {
		if (getNamespace() != null) {
			return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
		}
		else {
			return new String[] {DEFAULT_CONFIG_LOCATION};
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值