直接上源码
/**
*Tell the subclass to refresh the intern+al bean factory
*告诉子类刷新内部bean工厂
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
继续步入得到
refreshBeanFactory();
@Override
protected final void refreshBeanFactory() throws BeansException {
//判断是否存在bean工厂,如果存在则销毁所有bean,关闭bean工厂
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建默认的bean工厂,DefaultListableBeanFactory beanFactory的实现类,实现了所有生产bean组件的接口,一个完美,功能最全的工厂
DefaultListableBeanFactory beanFactory = createBeanFactory();
//为容器设置一个序列化ID
beanFactory.setSerializationId(getId());
//定制工厂
customizeBeanFactory(beanFactory);
//加载我们的bean定义 类似于生产图纸
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
从上面代码可以得知,spring在初始化容器的时候会先去判断是否存在bean工厂,如果存在会对所有的bean进行销毁处理,关闭掉bean工厂。然后继续创建bean工厂,之后会设置容器序列化id,定制bean工厂的一些属性,最后加载BeanDefinition,然后将bean工厂设置本类的到属性中
继续跟进createBeanFactory()方法
protected DefaultListableBeanFactory createBeanFactory() {
//创建一个功能最全的bean工厂,我们可以吧spring当成一个大工厂,里面的每个接口组件是负责生产bean的零件,最后拼接成一个完整的工厂
return new DefaultListableBeanFactory(getInternalParentBeanFactory());getBeanFactory()
}
//判断父容器是不是属于ConfigurableApplicationContext容器,如果是调用父容器的getBeanFactory()获取bean工厂,如果不是则将自己设置为夫容器节点,
@Nullable
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
}
下面是DefaultListableBeanFactory的组件依赖图,可以看见DefaultListableBeanFactory的层级是最深的,实现了所有功能接口,是功能最完善的工厂
定制bean工厂的属性
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//判断是否复写了allowBeanDefinitionOverriding,spring用于处理重名bean的问题,当allowBeanDefinitionOverriding为true时,
//则表示会覆盖之前的bean,该值默认是false值,一般项目中需要将其值设置为ture
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//是否支持循环引用,默认是true支持循环引用的,如果设置为false,表示不支持,如果此时创建bean的时候发现有循环运用,则会抛异常
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
继续跟进loadBeanDefinitions(beanFactory)
//加载我们的bean定义 类似于生产图纸
loadBeanDefinitions(beanFactory);
该方法主要是加载bean的定义在我们的工厂中,bean定义可以类比为生产bean的图纸,里面记载了bean的名称。bean是否是单例的,是否懒加载,等等,当然bean定义被加载之后也是可以对bean定义进行修改的
//模板方法,把父类定义的足够高,以抛异常的形式强迫之类必须实现该方法,
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException;
我们采用的是读取xml的形式来初始化容器
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//获取一个XmlBeanDefinition资源加载器
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
/**
* 给加载器设置环境变量,
*/
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//初始化beanDefinitionReader资源加载器
initBeanDefinitionReader(beanDefinitionReader);
//根据bean定义的读取器,读取并加载BeanDefinitions
loadBeanDefinitions(beanDefinitionReader);
}
接着跟进去loadBeanDefinitions(beanDefinitionReader)
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
//省略其他代码,主要是这一行进行真正的加载
int count = loadBeanDefinitions(resources);
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
//spring里面,凡是带do的都是真正干活的
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
/**
* 注册beanDefinition ,到此开始注册bean定义信息
*/
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
}
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//留给子类重写,类似前置处理器,这里spring预留了拓展点,给子类进行前置和后置处理
preProcessXml(root);
//真正解析bean定义信息
parseBeanDefinitions(root, this.delegate);
//留给子类重写,类似后置处理器
postProcessXml(root);
this.delegate = parent;
}
至此obtainFreshBeanFactory()方法就讲解完毕,到此我们的bean工厂就已经注册好了bean的定义和一些bean工厂的定制信息,