obtainFreshBeanFactory() 方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 抽象方法,由子类来实现
refreshBeanFactory();
// 抽象方法,由子类来实现。返回上一步创建的 BeanFactory
return getBeanFactory();
}
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
分为两种情况:
一、继承自AbstractRefreshableApplicationContext抽象类
refreshBeanFactory() 方法会关闭原有 BeanFactory ,再创建新的 BeanFactory ,并解析所有 Spring 配置文件(通常我们会放在 resources 目录下),将所有 Spring 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中。如果解析到
上面提到的 “加载到 BeanFactory 中” 的内容主要指的是添加到以下3个缓存:
- beanDefinitionNames缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 集合。
- beanDefinitionMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和 BeanDefinition 映射。
- aliasMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和别名映射。
@Override
protected final void refreshBeanFactory() throws BeansException {
// 存在 BeanFactory ,则销毁 Beans ,关闭 BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建 BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 自定义配置
customizeBeanFactory(beanFactory);
// 从 XML 配置文件或 Properties 配置文件或注解中加载 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);
}
}
// 从 XML 配置中加载 Bean 定义。由于目前 SpringBoot 是主流,这里就不深入研究啦。
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException;
// 可以在子类中重写该方法,进行自定义配置
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
// 是否允许覆盖同名称的不同定义的对象
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 是否允许bean之间存在循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
二、继承自GenericApplicationContext类
refreshBeanFactory() 方法仅为 BeanFactory 属性 serializationId 赋值。因为已经拥有一个内部 BeanFactory 子类可以通过公共方法来注册bean。SpringBoot Web 使用的 IoC 实现类为 AnnotationConfigServletWebServerApplicationContext ,该类间接继承了 GenericApplicationContext 。
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
本文由 Administrator 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站部分文章采集自互联网,因某些原因未注明出处,如有侵权,请留言告知。