【接上文】
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,属性参数都是默认值.
【小结】
- 获取到崭新的BeanFactory实例,如果实例化之前已经存在则进行销毁。
- 对ClasspathXmlApplicationContext加载beanDefinition
【NEXT】接下来就要对BeanFactory做一些初始化或者赋值操作,也就是下面的prepareBeanFactory方法做的事。