public static void main( String[] args ) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
Spring Ioc初始化一共分为三个步骤:定位,加载,注册。定位就是找到Bean的配置信息,加载就是读取Bean的配置信息,注册就是将Bean的配置信息注册到IOC容器。
本篇是IOC初始化的第一步,定位。
通过构造器启动Spring容器
//构造器,传入一个配置文件的路径,支持多个配置文件,走重载的构造方法
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
//实际上是调用了这个构造器
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);//调用父类构造器,生成资源加载器
setConfigLocations(configLocations);//设置配置文件
if (refresh) {
refresh();//启动Spring容器
}
}
先看一下ClassPathXmlApplicationContext构造器的第一步做了什么
//ClassPathXmlApplicationContext 的父构造器
public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {
super(parent);
}
//AbstractXmlApplicationContext 的父构造器
public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {
super(parent);
}
//AbstractRefreshableConfigApplicationContext 的父构造器
public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) {
super(parent);
}
//AbstractRefreshableApplicationContext 的父构造器 这里做了两件事
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
this();//设置一个资源加载器,以后可以加载资源
setParent(parent);
}
//先看AbstractApplicationContext 构造器中的第一步
//这里会获取一个资源加载器
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
//获取资源加载器
protected ResourcePatternResolver getResourcePatternResolver() {
//AbstractApplicationContext的继承关系
//public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext
//AbstractApplicationContext继承DefaultResourceLoader,因此也是一个资源加载器
return new PathMatchingResourcePatternResolver(this);
}
//PathMatchingResourcePatternResolver 的构造器,将AbstractApplicationContext资源加载器设置给自己的成员变量
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
//设置Spring的资源加载器
this.resourceLoader = resourceLoader;
}
//再看AbstractApplicationContext 构造器中的第二步
//上面ClassPathXmlApplicationContext 调用的时候,传进来的是null,就什么都没做
@Override
public void setParent(@Nullable ApplicationContext parent) {
this.parent = parent;
if (parent != null) {
Environment parentEnvironment = parent.getEnvironment();
if (parentEnvironment instanceof ConfigurableEnvironment) {
getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
}
}
}
结合来看,ClassPathXmlApplicationContext 构造器的第一步就是生成了一个资源加载器
再看一下ClassPathXmlApplicationContext构造器的第二步做了什么//调用了父类 AbstractRefreshableConfigApplicationContext 的方法
//传入配置文件路径,可能为多个
public void setConfigLocations(@Nullable 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;
}
}
//解析配置文件路径
protected String resolvePath(String path) {
return getEnvironment().resolveRequiredPlaceholders(path);
}
//调用了父类 AbstractApplicationContext 的方法,获取环境
//上面可以看到,如果第一步传入的参数不为null,也会调用这个方法
@Override
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}
//AbstractApplicationContext 的方法,生成一个标准的环境
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
//解析
@Override
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
return this.propertyResolver.resolveRequiredPlaceholders(text);
}
// propertyResolver 的由来
protected final Log logger = LogFactory.getLog(getClass());
private final MutablePropertySources propertySources = new MutablePropertySources(this.logger);
private final ConfigurablePropertyResolver propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);
//解析必要的占位符
@Override
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
if (this.strictHelper == null) {
this.strictHelper = createPlaceholderHelper(false);
}
return doResolvePlaceholders(text, this.strictHelper);
}
//创建占位符处理器
private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
return new PropertyPlaceholderHelper(this.placeholderPrefix, this.placeholderSuffix,
this.valueSeparator, ignoreUnresolvablePlaceholders);
}
//入参分别是占位符前缀(${),占位符后缀(}),值分隔符(:),是否忽略解析占位符
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
@Nullable String valueSeparator, boolean ignoreUnresolvablePlaceholders) {
Assert.notNull(placeholderPrefix, "'placeholderPrefix' must not be null");
Assert.notNull(placeholderSuffix, "'placeholderSuffix' must not be null");
this.placeholderPrefix = placeholderPrefix;
this.placeholderSuffix = placeholderSuffix;
String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix);
if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) {
this.simplePrefix = simplePrefixForSuffix;
}
else {
this.simplePrefix = this.placeholderPrefix;
}
this.valueSeparator = valueSeparator;
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
}
//wellKnownSimplePrefixes 的初始化 是个静态块
static {
wellKnownSimplePrefixes.put("}", "{");
wellKnownSimplePrefixes.put("]", "[");
wellKnownSimplePrefixes.put(")", "(");
}
//解析占位符,返回资源地址
private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
return helper.replacePlaceholders(text, this::getPropertyAsRawString);
}
//下面不再跟了
可以看出来,这一步主要是解析资源文件位置,并生成占位符解析器
再看一下ClassPathXmlApplicationContext构造器的第三步做了什么public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {//加锁
//调用容器准备刷新的方法,获取容器的当时时间,设置启动标志,验证必要的属性,生成空的事件集合
prepareRefresh();
//ioc的初始化在这里
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
//BeanFactory后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
//bean后置处理器
registerBeanPostProcessors(beanFactory);
//初始化信息源
initMessageSource();
//初始化容器事件传播器.
initApplicationEventMulticaster();
//调用子类的某些特殊Bean初始化方法
onRefresh();
//注册事件监听器.
registerListeners();
//初始化非lazy的bean
finishBeanFactoryInitialization(beanFactory);
//发布容器事件,结束refresh
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
//销毁已创建的Bean
destroyBeans();
//取消refresh操作
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
spring容器在第三步,refresh方法中初始化,具体是在 obtainFreshBeanFactory 方法中
下面看obtainFreshBeanFactory 方法 //获得新的BeanFactory
//AbstractApplicationContext#obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新BeanFactory
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
//刷新BeanFactory在AbstractRefreshableApplicationContext#refreshBeanFactory方法中实现
protected final void refreshBeanFactory() throws BeansException {
//如果已经有容器,销毁容器中的bean,关闭容器
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建IOC容器
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//对IOC容器进行定制化
customizeBeanFactory(beanFactory);
//加载BeanDefinition ioc初始化第二步
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
//创建IOC容器
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
//AbstractApplicationContext#getInternalParentBeanFactory 这里会返回null
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext) ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
}
//private ApplicationContext parent; 在上面构造器的第一步传入的parent是 null
public ApplicationContext getParent() {
return this.parent;
}
//看看 DefaultListableBeanFactory 构造器做了啥
public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
super(parentBeanFactory);
}
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
this();
setParentBeanFactory(parentBeanFactory);
}
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
public AbstractBeanFactory() {
}
public void setParentBeanFactory(@Nullable BeanFactory parentBeanFactory) {
if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
}
this.parentBeanFactory = parentBeanFactory;
}
//这一步构造了ioc容器,AbstractBeanFactory
//定制化ioc容器
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//是否允许beanDefinition重写
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//是否允许循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
这个过程是ioc初始化的第一步,初始化资源,Beanfactory,获取Bean定位



