Spring 单例详细实例化主要流程
2022-04-26 15:54:37 0 举报
单例实例化流程,详细流程
作者其他创作
大纲/内容
mbd.isSingleton()
实例化Bean
NO
YES
factorybean处理
从缓存中拿实例
isPrototypeCurrentlyInCreation(beanName)
把beanName添加到singletonsCurrentlyInCreation Set容器中
循环beanNames
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))
进行有参构造方法推断并实例化
调用
mbd.getPreferredConstructors()
mbd.getFactoryMethodName() != null
经过一系列配置,如类型转换器
if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName)
TargetSource接口的运用
抛出异常
是否为单例
有带有@Autowired注解的构造函数或者BeanDefinition中指定了构造方法参数值 使用了 <constructor-arg>标签或者在getBean()时指定了args
入口方法
远程或其他模式
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed())
返回实例
autowireNecessary表示采用有参构造函数注入
getBean(beanName)
sharedInstance != null && args == null
synchronized (this.singletonObjects)
判断当前bd是单例
采用有参并且参数确定的构造函数注入
isFactoryBean(beanName)
验证并准备为此bean定义的方法overrides
存在factorMethod方法或者bean对象是由@Bean注解创建
throw new BeanCurrentlyInCreationException(beanName)
if (resolved)
singletonObject = singletonFactory.getObject()
返回bean
通过factoryMethod实例化这个bean
!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
不是抽象的,是单例的,非懒加载的就实例化
singletonObjects:加入单例一级缓存singletonFactories:从三级缓存中删除earlySingletonObjects:从二级缓存中删除registeredSingletons:加入已注册单例set名称集合
获取所有带有@Autowired注解的构造函数
markBeanAsCreated(beanName)
Bean类不是公共的,不允许非公共访问
锁定一级缓存
若是新创建的Bean
DefaultListableBeanFactory.preInstantiateSingletons()
if (args == null)
Object sharedInstance = getSingleton(beanName);
判断指定的原型bean当前是否正在创建中(在当前线程内)
该方法是FactoryBean接口的调用入口
beforeSingletonCreation(beanName)
获取factoryBean对应BeanWrapper
esolved为true,表示当前bean的构造方法已经确定了,也代表该Bean之前被解析过如果autowireNecessary为true说明是采用有参构造函数注入
断bean是否实现了FactoryBean接口
这一步也是必须要做的,若存在父容器,得看看父容器是否实例化过它。避免被重复实例化
从父容器获取Bean
验证并准备为此bean定义的方法overrides。检查是否存在具有指定名称的方法
当作用域为原型、多次调用getBean()时,不传入参数,从缓存中获取这段逻辑才会被执行
判断是否获取到实例
缓存获取Bean
获取到bean
存在创建Bean回调Supplier
先创建以来Bean实例
将指定的bean标记为已创建(或即将创建)
获取实例对应的BeanWrapper
创建单例对象
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)
dependsOn != null
存在默认构造的首选构造函数
parentBeanFactory != null && !containsBeanDefinition(beanName)
if (autowireNecessary)
获取类对应的Class对象
待分析
0 条评论
回复 删除
下一页