文章目录
Spring源码自学笔记
从ClassPathXmlApplicationContext开始
ClassPathXmlApplicationContext的创建流程
ClassPathXmlApplicationContext的继承顺序还是挺复杂的
首先看构造函数中的执行过程
然后判断是否要刷新
如果刷新,则执行refresh
方法去刷新环境变量
refresh
方法还比较重要,里面有创建很多东西
代码如下
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
refresh()方法
ClassPathXmlApplication没有实现refresh方法,使用的父类AbstractRefreshableConfigApplicationContext实现的refresh方法,该方法由ConfigurableApplicationContext
声明
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 为刷新做准备
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 让子类去出刷新Bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
环境属性配置
AbstractEnvironment
public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";
public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";
// 配置使用LinkedHashSet, 保证配置属性的唯一性,并且还可以保证有序性
private final Set<String> activeProfiles = new LinkedHashSet<String>();
// getReservedDefaultProfiles() 方法返回一个 Collections.SingletonSet类型,值就为 default
private final Set<String> defaultProfiles = new LinkedHashSet<String>(getReservedDefaultProfiles());
//PropertySources 的默认实现,用于存储属性PropertySources.
// 保存的主要有 systemProperties 和 systemEnvironment
// 分别存放 jvm的属性 和 系统的属性
private final MutablePropertySources propertySources = new MutablePropertySources(this.logger);
// 创建一个属性解析器,这里使用PropertySourcesPropertyResolver 继承于 AbstractPropertyResolver
private final ConfigurablePropertyResolver propertyResolver =
new PropertySourcesPropertyResolver(this.propertySources);
AbstractPropertyResolver
使用到 SystemPropertyUtils
中的配置
StandardEnvironment
最后创建一个StandardEnvironment类
Assert用法总结
// 判断每个元素的都不能为空
Assert.noNullElements(locations, "Config locations must not be null");
我怎么感觉漏了好多,一定是有哪里错过了
还要慢慢看
跟着源码一次过下来
莫名奇妙的地方太多了
加油!