【spring】

先看一个简单的程序:

package com.shadow;
import com.shadow.framework.DataSourceConfig;
import com.shadow.framework.OwnClassPathXmlApplicationContext;
import com.shadow.model.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map;
public class TestIoc {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext ac = new OwnClassPathXmlApplicationContext("spring.bean.xml");
		User user =(User) ac.getBean("user");
		System.out.println(user);
		Map<String, Object> systemProperties = ac.getEnvironment().getSystemProperties();
		for (Map.Entry<String, Object> stringObjectEntry : systemProperties.entrySet()) {
			if("spring5.0".equalsIgnoreCase(stringObjectEntry.getKey())){
				System.out.println("key:"+stringObjectEntry.getKey());
				System.out.println("value:"+stringObjectEntry.getValue());
			}
		}
		System.out.println("*******************");
		DataSourceConfig dataSourceConfig =(DataSourceConfig) ac.getBean("dataSourceConfig");
		System.out.println(dataSourceConfig.getUserName());
		System.out.println(dataSourceConfig.getPassWord());
		System.out.println(dataSourceConfig.getUrl());
	}
}

从OwnClassPathXmlApplicationContext构造方法说起。具体代码如下。不难发现有参构造中调用了父类ClassPathXmlApplicationContext的构造方法,然后this函数又调用了本类的有参构造。具体三段代码如下。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

重点看下setConfigLocations方法,目的设置应用上下文的配置路径,
然后看下AbstractRefreshableConfigApplicationContext父类中resolvePath方法。
由生出的getEnvironment方法生成一个StandardEnvironment ,
发现重写了父类AbstractEnvironment中的customizePropertySources方法。获取到了 当前JVM 设置的属性值, Java进程变量。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/2cc649f713fe4851acb075685f95d869.png在这里插入图片描述
在这里插入图片描述

紧接着进入resolveRequiredPlaceholders()方法
strictHelper为空,new一个PropertyPlaceholderHelper,进入PropertyPlaceholderHelper构造方法。
然后调用doResolvePlaceholders方法,在
继续调用replacePlaceholders方法
在进入parseStringValue方法,因为我的配置文件不包含$缀,这里直接返回了。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

再看refresh()方法,调用父类AbstractApplicationContext中refresh()方法

第一个方法:prepareRefresh

protected void prepareRefresh() {
		// 当前启动时间戳
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		初始化上下文环境中的任何占位符属性资源
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		验证标记为"必须"的所有属性是否可以解析
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		//初始化或者重置earlyApplicationListeners
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

第二个方法:obtainFreshBeanFactory 返回默认的DefaultListableBeanFactory
customizeBeanFactory自定义beanFactory ,包括是否允许定义bean名称覆盖,以及循环引用。
loadBeanDefinitions
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值