Bean 的加载
一、整体时序图
1、入口:
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beanfactory-test.xml"));
TestBean testBean = (TestBean) beanFactory.getBean("testBean");
其中获取 bean 的函数 beanFactory#getBean 就是我们的入口,跟踪入口,可以看到源码如下:
AbstractBeanFactory#getBean
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//提取对应的 beanName
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
// 检查缓存中或者实例工厂中是否有对应的实例
// 为什么首先会使用这段代码呢?
// 因为在创建单例 bean 的时候,会存在依赖注入的情况,而创建依赖的时候,为了避免循环依赖
// Spring 创建 bean 的原则是不等 bean 创建完成,就会将创建 bean 的 ObjectFactory 提早曝光
// 也就是将 ObjectFactory 加入到缓存中,一旦下个 bean 创建的时候,需要依赖上个 bean 则直接使用 ObjectFactory
// 下面代码是尝试直接从缓存中获取或者 singletonFactories 中的 ObjectFactory 中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//返回对应的实例,有时候存在诸如 BeanFactory 的情况,并不是直接返回实例本身,而是返回指定方法返回的实例
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//只有单例情况下,才会尝试解决循环依赖.
//如果存在 A 中有属性 B,B 中又有属性 A,那么当依赖注入的时候,
//就会产生当 A 还未创建完成的时候,由于创建 A 需要先创建 B,而创建 B 又需要先创建 A,
//就造成了循环依赖,也就是下面 isPrototypeCurrentlyInCreation(beanName) 为 true
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果 beanDefinitionMap 中(即所有已加载的类中)不包括 beanName,
//则尝试从 parentBeanFactory 中检测
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
//递归到 BeanFactory 中寻找
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
//有参,委托给父级
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null)