文章目录
前言
体能状态先于精神状态,习惯先于决心,聚焦先于喜好。
承上启下
本方法用于将配置文件中的bean加载到 beanDefination 中,然后将beanDefination 放入到 beanFactory,但是需要注意到是,只是加载了 bean到定义信息,还没有进行注入、实例化等工作.
AbstractApplicationContext.obtainFreshBeanFactory(
org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(
通知子类 refresh 内部的 bean factory
/**
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//创建一个 beanFactory 对象
refreshBeanFactory();
//bean配置文件加载和解析工作已经完成,这里只是简单的验证一下非空,如果非空则返回已加载完毕的值
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
AbstractRefreshableApplicationContext.refreshBeanFactory(
org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(
用于创建一个BeanFactory(DefaultListableBeanFactory ),为之后使用,如果之前的操作存在这么个 BeanFactory,则先将之前的 BeanFactory 进行销毁。
新创建的 BeanFactory 将服务于 下一阶段 上下文的声明周期
@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果 beanFactory已存在,则销毁,这里的操作都是用了 对象锁进行同步
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建 BeanFactory,内部会检测父工厂,默认父工厂为null
DefaultListableBeanFactory beanFactory = createBeanFactory();
//设置序列化id,以 webApplicationContext 的id相同
beanFactory.setSerializationId(getId());
//更新 allowBeanDefinitionOverriding 和 allowCircularReferences 的值,默认这段代码没用,不会修改默认值,除非你beanFactory.set*Name 修改了值
customizeBeanFactory(beanFactory);
//为 beanFactory 记载 bean定义文件
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
createBeanFactory()
看这个方法建议先看下 认识 DefaultListableBeanFactory,这里面有对 DefaultListableBeanFactory 和其父类的基本常量的介绍。
比如默认cglib动态代理、允许覆盖同名bean、允许循环依赖、允许立即加载需要的类、不允许使用原始类型注入作为解决循环依赖的方法等等。
再一个需要忽略依赖和注入的接口,默认只有 BeanFactory interface,但是在 DefaultListableBeanFactory 中其实增加了 BeanNameAware、BeanFactoryAware和BeanClassLoaderAware 三个接口要被忽略
protected DefaultListableBeanFactory createBeanFactory() {
//getInternalParentBeanFactory() 返参默认为null,即没有父工厂
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
loadBeanDefinitions(beanFactory);
org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(
这个步骤比较关键,用于加载定义 bean 的配置文件,一般我们会定义一个或者多个 applicationContext.xml,当然,这个功能最终是体现在 loadBeanDefinitions(beanDefinitionReader); 中的
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//为 beanFactory 创建一个 XmlBeanDefinitionReader 对象
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 使用上下文资源加载 变量参数,配置 bean 定义的reader
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 允许一个子列提供自定义的 reader对象的实现,然后再开始具体bean 定义加载过程
//默认这是一个空方法
initBeanDefinitionReader(beanDefinitionReader);
//正式加载
loadBeanDefinitions(beanDefinitionReader);
}
XmlWebApplicationContext.loadBeanDefinitions(
org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(
使用 XmlBeanDefinitionReader 加载 bean定义文件。
bean factory的声明周期由 refreshBeanFactory 方法控制,本方法仅用于加载或者注册 bean定义文件。
内部委托 ResourcePatternResolver 将本地文件进行解析为资源实例。对于这部分逻辑的解析再写一篇文章 reader.loadBeanDefinitions(configLocation);
* <p>Delegates to a ResourcePatternResolver for resolving location patterns
* into Resource instances.
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
//考虑通配符的情况,对文件路径进行转化
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
//内部委托 ResourcePatternResolver 将本地文件进行解析为资源实例
reader.loadBeanDefinitions(configLocation);
}
}
}
AbstractRefreshableApplicationContext.getBeanFactory()
org.springframework.context.support.AbstractRefreshableApplicationContext.getBeanFactory()
这个方法没有特别复杂的逻辑,只是判断一下 beanFactory 是否存在
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}