4.refresh-obtainFreshBeanFactory方法详解

【接上文】

2. obtainFreshBeanFactory()

AbstractApplicationContext#obtainFreshBeanFactory

/**
 * Tell the subclass to refresh the internal bean factory.
 * 告诉子类将要刷新内部beanFactory
 * @return the fresh BeanFactory instance
 * @see #refreshBeanFactory()
 * @see #getBeanFactory()
 */
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}
//---------------------------------------------------------------------
// Abstract methods that must be implemented by subclasses
//---------------------------------------------------------------------
/**
* Subclasses must implement this method to perform the actual configuration load.
* 子类必须实现这个方法来完成真正的配置加载
* The method is invoked by {@link #refresh()} before any other initialization work.
* 这个方法被refresh在其他的初始化工作开始之前调用
* <p>A subclass will either create a new bean factory and hold a reference to it,
* or return a single BeanFactory instance that it holds. 
* 子类要么创建一个新的beanfactory,要么持有这样一个引用,要么返回一个持有的一个单例beanFactory
* In the latter case, it will usually throw an IllegalStateException if refreshing the context more than once.
* 在后面这种情况下,如果刷新上下文多次会抛出IllegalStateException
* @throws BeansException if initialization of the bean factory failed
* @throws IllegalStateException if already initialized and multiple refresh
* attempts are not supported
*/
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

/**
* Subclasses must return their internal bean factory here. They should implement the
* lookup efficiently, so that it can be called repeatedly without a performance penalty.
* <p>Note: Subclasses should check whether the context is still active before
* returning the internal bean factory. The internal factory should generally be
* considered unavailable once the context has been closed.
* 子类必须返回他们内置的beanFactory,他们应当高效的实现该方法,以便可以重复调用而不需要顾虑性能。
* 需要注意的是子类在返回结果之前必须检查上下文是否仍然可用。如果上下文被关闭则beanFactory应当是不可用的。
* @return this application context's internal bean factory (never {@code null})
* @throws IllegalStateException if the context does not hold an internal bean factory yet
* (usually if {@link #refresh()} has never been called) or if the context has been
* closed already
* @see #refreshBeanFactory()
* @see #closeBeanFactory()
*/
@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

这两个方法的直接实现子类有AbstractRefreshableApplicationContext和GenericApplicationContext,分别是ClasspathXmlApplicationContext和AnnotationConfigApplicationContext的超级父类。下面分别来看这两个类。

GenericApplicationContext#refreshBeanFactory

/**
 * Create a new GenericApplicationContext.
 * @see #registerBeanDefinition
 * @see #refresh
 */
public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

/**
* Do nothing: We hold a single internal BeanFactory and rely on callers
* to register beans through our public methods (or the BeanFactory's).
* @see #registerBeanDefinition
*/
@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());
}

/**
* Return the single internal BeanFactory held by this context
* (as ConfigurableListableBeanFactory).
*/
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
    return this.beanFactory;
}

可以看到这个的实现比较简单,单纯的设置了序列化id,而getBeanFactory返回的其实也是new出来的DefaultListableBeanFactory。

再看下另一个实现类的操作。

AbstractRefreshableApplicationContext#refreshBeanFactory

/**
 * This implementation performs an actual refresh of this context's underlying
 * bean factory, shutting down the previous bean factory (if any) and
 * initializing a fresh bean factory for the next phase of the context's lifecycle.
 */
@Override
protected final void refreshBeanFactory() throws BeansException {
    //如果存在BeanFactory 则销毁并关闭(清空缓存的bean, beanFactoty置空并修改各种状态)
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try 
      //创建新的beanFactory实际是DefaultListableBeanFactory的实例
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      //设置序列化id
      beanFactory.setSerializationId(getId());
      // 初始化beanFactory的一些配置 如是否允许bean覆盖、是否允许循环引用
      customizeBeanFactory(beanFactory);
      // 加载bean定义信息 通过读取xml文件组装bean定义信息,实现在AbstractXmlApplicationContext中,
      loadBeanDefinitions(beanFactory);
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
    DefaultListableBeanFactory beanFactory = this.beanFactory;
    if (beanFactory == null) {
        throw new IllegalStateException("BeanFactory not initialized or already closed - " +
                                        "call 'refresh' before accessing beans via the ApplicationContext");
    }
    //这里实际就是new出来的DefaultListableBeanFactory
    return beanFactory;
}

protected DefaultListableBeanFactory createBeanFactory() {
    return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

/**
* 初始化beanFactory的一些配置 如是否允许bean覆盖、是否允许循环引用
*/
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    if (this.allowBeanDefinitionOverriding != null) {
        beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    if (this.allowCircularReferences != null) {
        beanFactory.setAllowCircularReferences(this.allowCircularReferences);
    }
}

AbstractXmlApplicationContext#loadBeanDefinitions

/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see #initBeanDefinitionReader
* @see #loadBeanDefinitions
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    //TODO 这里是真正解析xml文件组装bean的方法,后续再做分析
    loadBeanDefinitions(beanDefinitionReader);
}

涉及到的类及方法如下:

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { 
    
    /**
     * Create new XmlBeanDefinitionReader for the given bean factory.
     * @param registry the BeanFactory to load bean definitions into,
     * in the form of a BeanDefinitionRegistry
     */
    public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
        //调用了父类的构造方法
        super(registry);
    }
    //其他暂时省略
}

public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader, EnvironmentCapable {
    
    protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        this.registry = registry;

        // Determine ResourceLoader to use.
        if (this.registry instanceof ResourceLoader) {
            this.resourceLoader = (ResourceLoader) this.registry;
        }
        else {
            this.resourceLoader = new PathMatchingResourcePatternResolver();
        }
        // Inherit Environment if possible
        if (this.registry instanceof EnvironmentCapable) {
            this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
        }
        else {
            this.environment = new StandardEnvironment();
        }
    }

}

可以看到AbstractBeanDefinitionReader的构造方法中只是给当前类的部分属性赋值,里面的registry是DefaultListableBeanFactory.

至此obtainBeanFactory就分析完了,也获取到了BeanFactory的实例,即DefaultListableBeanFactory,属性参数都是默认值.

【小结】

  1. 获取到崭新的BeanFactory实例,如果实例化之前已经存在则进行销毁。
  2. 对ClasspathXmlApplicationContext加载beanDefinition

【NEXT】接下来就要对BeanFactory做一些初始化或者赋值操作,也就是下面的prepareBeanFactory方法做的事。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泽济天下

你的鼓励是我最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值