Spring源码:getBean流程
1 doGetBean
-
transformedBeanName,处理别名BeanName、处理带&符的工厂BeanName。
-
getSingleton,先尝试从缓存中获取Bean实例,这个位置就是三级缓存解决循环依赖的方法。
-
getObjectForBeanInstance,如果 sharedInstance 是普通的 Bean 实例,则下面的方法会直接返回。另外 sharedInstance 是工厂Bean类型,则需要获取 getObject 方法,可以参考关于 FactoryBean 的实现类。
-
isPrototypeCurrentlyInCreation,循环依赖有三种,setter注入、多实例和构造函数,Spring 只能解决 setter 注入,所以这里是 Prototype 则会抛出异常。
-
getParentBeanFactory,父 bean 工厂存在,当前 bean 不存在于当前bean工厂,则到父工厂查找 bean 实例。
-
originalBeanName,获取 name 对应的 beanName,如果 name 是以 & 开头,则返回 & + beanName
-
args != null,根据 args 参数是否为空,调用不同的父容器方法获取 bean 实例
-
!typeCheckOnly,typeCheckOnly,用于判断调用 getBean 方法时,是否仅是做类型检查,如果不是只做类型检查,就会调用 markBeanAsCreated 进行记录
-
mbd.getDependsOn,处理使用了 depends-on 注解的依赖创建 bean 实例
-
isDependent,监测是否存在 depends-on 循环依赖,若存在则会抛出异常
-
registerDependentBean,注册依赖记录
-
getBean(dep),加载 depends-on 依赖(dep 是 depends-on 缩写)
-
mbd.isSingleton(),创建单例 bean 实例
-
mbd.isPrototype(),创建其他类型的 bean 实例
-
return (T) bean,返回 Bean 实例
/** |
2 transformedBeanName
protected String transformedBeanName(String name) { |
-
使用 FactoryBean 创建出的对象,会在 DefaultListableBeanFactory 初始化的时候,使用 getBean(FACTORY_BEAN_PREFIX + beanName) 给 beanName 加上 &
(String FACTORY_BEAN_PREFIX = "&")
preInstantiateSingletons(){ |
3 getSingleton:从缓存中获取 bean 实例
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { |
-
singletonObjects:用于存放初始化好的 bean 实例。这里的bean是已经创建完成的,该bean经历过实例化->属性填充->初始化以及各类的后置处理。
-
earlySingletonObjects,用于存放初始化中的 bean,来解决循环依赖。
-
singletonFactories,用于存放 bean 工厂,bean 工厂所生成的 bean 还没有完成初始化 bean。
4 depends-on 依赖 Bean
AbstractBeanFactory -> isDependent(beanName, dep) -> DefaultSingletonBeanRegistry.class
//isDependent(beanName, dep) |
dependentBeanMap:依赖bean的map,即key是被依赖的bean。记录一个bean被多少bean依赖;(该bean被多少bean当做成员变量用@Resource、@Autowired修饰)
dependenciesForBeanMap:bean的依赖,即value是被依赖的bean。记录一个bean依赖了多少bean;(通俗点:一个bean里面有多少个@Atuwowired、@Resource)
java - dependentBeanMap和dependenciesForBeanMap的区别 - 个人文章 - SegmentFault 思否
5 getSingleton:获取单实例bean
if (mbd.isSingleton()) { |
-
this.singletonObjects.get(beanName),先尝试从缓存池中获取对象,没有就继续往下执行
-
beforeSingletonCreation(beanName),标记当前 bean 被创建,如果有构造函数注入的循环依赖会报错
-
singletonObject = singletonFactory.getObject(),创建 bean 过程就是调用 createBean() 方法
-
afterSingletonCreation(beanName),最后把标记从集合中移除
-
addSingleton(beanName, singletonObject),新创建的会加入缓存集合
6 FactoryBean 中获取 bean 实例
getObjectForBeanInstance->getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { |
7 createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { |
8 doCreateBean
/** |
9 getMergedBeanDefinition
在Spring中用BeanDefinition来代表一个Spring对象的定义。因此有BeanDefinitionBuilder、BeanDefinitionParser这些常见工具类。简单来说,整个Spring容器也就是读取文件、构造BeanDefinition对象、实例化成Bean的过程。BeanDefinition也可以认为是一个Bean元数据的容器,包含了一个bean实例化和初始化所需要的各种参数,比如class、name、scope、properties等等。