Spring 源码核心实例化解析流程
2022-01-18 18:23:44 0 举报
精通spring源码流程图 交流可加微信xri2117
作者其他创作
大纲/内容
不是重点 执行加载bean class
获取
true | false
transformedBeanName(name)
缓存是否为空
实例化 + ioc 依赖注入完成以后调用1. 调用 Aware方法2. 特殊方法调用 比如 @PostConstruct Aware接口3. InitializingBean 接口,afterPropertiesSet,init-method 属性调用4. aop入口
获取 LifecycleMetadata 对象这个 metadata 主要就是收集两个注解的方法 @PostConstruct @PreDestroy
作用不大 这里非常有意思,写接口可以让所有类都不能依赖注入 实现InstantiationAwareBeanPostProcessor 返回false 无法依赖注入
解析时,把所有 beanName 都缓存到 beanDefinitionNames 容器中
isFactoryBean(beanName)
调用getBean
是
创建容器
否
是否有缓存
所有单例的bean都创建完 执行实现了 SmartInitializingSingleton接口的方法
获取带有注解@Autowired不为空的话进行实例化ctors != null
获取候选的参数 触发getBean
顶级BeanPostProcessor接口span style=\"font-size: inherit;\
Field field = (Field) this.member
加入缓存
回调lambda函数
返回true false
触发getBean
BeanPostProcessor 场景调用 核心的几个InitDestroyAnnotationBeanPostProcessor 对 @PostConstruct 注解的支撑ApplicationContextAwareProcessor 对 一些 Aware 接口的支撑ImportAwareBeanPostProcessor 是 ConfigurationClassPostProcessor 内部类 对 ImportStack的支撑
核心方法 但是大部分情况不会走这里只有两种情况会走这个if里面 != null <bean factory-method=\"\" 标签里配置中了 factory-method 属性方法上 加了 @Bean 的注解
从一级缓存获取getSingleton
(beanInstance instanceof FactoryBean)
把反射出来的实例化对象包装到 BeanWrapper
从缓存中获取 Metadata 对象
不为空
bean实例化的后置处理器
加入提前aop容器
处理器@Autowired后置处理器
创建实例
bean是否被实例化
@Autowired 属性注入是 AutowiredFieldElement 内部类@Autowired 方法注入是 AutowiredMethodElement 内部类@Resource 属性注入是 InjectedElement 内部类
InstantiationAwareBeanPostProcessor
postProcessAfterInstantiation 这个方法只要返回 false 就 return 直接返回无法走下面的依赖注入代码了
获取合并后的beanDfinition 继续判断是否FactoryBean
mbd.getFactoryMethodName() != null
AutowiredAnnotationBeanPostProcessor 处理 @Autowired
InitDestroyAnnotationBeanPostProcessor 对 @PostConstruct 注解的支撑
从三级缓存获取 singletonFactory.getObject() 触发这个函数式方法BeanPostProcessor应用 进行AOP
getEarlyBeanReference
buildLazyResolutionProxy
return BeanUtils.instantiateClass(constructorToUse)
SmartInstantiationAwareBeanPostProcessor
Set<String> singletonsCurrentlyInCreation
删除
核心功能 IOC DI 依赖注入
this.earlySingletonObjects.get(beanName)
核心实例化
如果代码能走下来,则说明 beanName 不是以&开头,并且 beanInstance 是 FactoryBean类型的
获取依赖属性
elements 容器和当前寻找的类 进行包装成 InjectionMetadata 对象
if (singletonFactory != null)从三级缓存执行lambda函数
调用实现了 SmartInitializingSingleton 接口的方法
ReflectionUtils.doWithLocalFields
是否支持循环依赖 并且是是正在创建的
return bean;
否、执行创建bean
List<BeanPostProcessor> beanPostProcessors
for (String beanName : beanNames)
DestructionAwareBeanPostProcessor
返回属性进行依赖注入
依次调用
寻找依赖
从一级缓存获取
实现了 Aware 接口的方法
核心方法 获取 field 上面的 @Autowired 注解并封装成对象 doWithLocalFields 循环查找
clazz.getDeclaredConstructor()
如果是SmartFactoryBean实例 并且 isEagerInit重写返回true
这个方法是spring中最重要的方法1、bean实例化过程2、ioc3、注解支持4、BeanPostProcessor 的执行5、Aop的入口
判断是否是 MergedBeanDefinitionPostProcessor 类型 AutowiredAnnotationBeanPostProcessor CommonAnnotationBeanPostProcessor
是否多例else if (mbd.isPrototype())
创建外层容器
判断是否带有&前缀
设置到 beanWrapper instantiate 通过构造函数进行反射创建 bean
返回实例
BeanPostProcessor 场景调用
触发构造函数中参数的 getBean 操作,会实例化参数的值
添加
return beanInstance
getBean
调用 FactoryBean接口的 重写的 factory.getObject 方法
determineRequiredStatus(ann)
把beanName添加到 singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean
返回包装过的实例
处理@Resource注解后置处理器
BeanPostProcessor
是否懒加载
MergedBeanDefinitionPostProcessor
buildResourceMetadata(clazz)
return wrappedBean
getBean(FACTORY_BEAN_PREFIX + beanName)
等待三级缓存调用
doCreateBean
从二级缓存获取
加二级缓存
BeanPostProcessor 接口的典型运用
执行顺序 1
if (bean instanceof Aware) {\t\t\tif (bean instanceof BeanNameAware) {\t\t\t\t((BeanNameAware) bean).setBeanName(beanName);\t\t\t}\t\t\tif (bean instanceof BeanClassLoaderAware) {\t\t\t\tClassLoader bcl = getBeanClassLoader();\t\t\t\tif (bcl != null) {\t\t\t\t\t((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);\t\t\t\t}\t\t\t}\t\t\tif (bean instanceof BeanFactoryAware) {\t\t\t\t((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);\t\t\t}\t\t}
调用InitializingBean接口,afterPropertiesSet,init-method属性
BeanPostProcessor容器
删除二级缓存
return object
提前代理容器
(mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName))
this.singletonObjects.get(beanName)
三级缓存
循环依赖的dependsOn 进行getBean
调用实现了 InitializingBean 接口的方法功能与 @PostConstruct 注解类似 但是调用顺序晚于 @PostConstruct
依赖注入元数据缓存
add
一级缓存是否为空
二级缓存
getBean(beanName);
AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors
核心方法 调用InitializingBean接口,afterPropertiesSet,init-method属性
实例化 instantiate
加载过直接返回return mbd.getBeanClass()
singletonObject == null && isSingletonCurrentlyInCreation(beanName)
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>()
加入一级缓存
创建bean实例1. 实例化 factoryMethod 方法对应的实2. 实例化带有 @Autowired 注解的构造函数3. 实例化没有 @Autowired 的有参构造函数4. 实例化无参构造函数 大部分都是无参构造
获取单例的 bean
getResourceToInject 会触发依赖注入引用类型的的 getBean操作
判断 filed 是否有 @Resource 注解
实例化前
beforeSingletonCreation(beanName)
调用解析时候注册的销毁方法 不是重点
this.injectionMetadataCache.get(cacheKey)
singletonFactory.getObject()
判断父类不是 object 再次循环
获取bean 函数是接口 回调createBean函数
添加到一级缓存
判断是不是FactoryBean 类型
获取依赖对象属性,依赖对象要先实例化
调用放入的lambda函数
invokeAwareInterfaces(bean)
获取 Resource metadata 元数据
ImportAwareBeanPostProcessor 是 ConfigurationClassPostProcessor 内部类 对 ImportStack的支撑
实例化前的 BeanPostProcessor 如果执行了方法后返回了对象,则不会机型后面的生命周期
field.isAnnotationPresent(Resource.class)
factory instanceof SmartFactoryBean
从一级缓存获取bean 提前暴露为 false
依赖注入
把父 BeanDefinition 里面的属性拿到子 BeanDefinition 中,进行合并
while (targetClass != null && targetClass != Object.class)
true
传入了 原 name 和 转换后的去掉 & 前缀的 beanName
执行函数
如果二级缓存可以获取到则return 如果获取不到并且是允许提前暴露则从三级缓存获取
对 beanNames 进行循环实例化
能找到则return如果找不到也不是在创建的也return null找不到 并且是正在创建的 则出现循环赖依执行下面代码
调用BeanPostProcessor方法
初始化bean
result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
从三级缓存获取
判断是否为空
返回
创建完成后 从 singletonsCurrentlyInCreation 正在创建的bean容器中 要删除该bean
pf.getProxy(beanFactory.getBeanClassLoader())
new BeanWrapperImpl(beanInstance)
大部分都是单例模式的 if (mbd.isSingleton())
可能发生do while 循环 所以把 currElements集合所有元素 加入到 循环外层 elements 新容器
进行类的代理
反射实例化
for (String dep : dependsOn)
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory)
注册bean 销毁时的类 DisposableBeanAdapter
缓存是否可以拿到实例
beanFactory.preInstantiateSingletons();
CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
反射调用
处理合并完成的BeanDefinition的后置处理器
顶级后置处理器
非常重要 循环依赖 添加三级缓存
获取 @Autowired 注解
创建bean
调用 init-method 配置的方法
判断是否被加载
if (bean instanceof EnvironmentAware) {\t\t\t((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());\t\t}\t\tif (bean instanceof EmbeddedValueResolverAware) {\t\t\t((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);\t\t}\t\tif (bean instanceof ResourceLoaderAware) {\t\t\t((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);\t\t}\t\tif (bean instanceof ApplicationEventPublisherAware) {\t\t\t((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);\t\t}\t\tif (bean instanceof MessageSourceAware) {\t\t\t((MessageSourceAware) bean).setMessageSource(this.applicationContext);\t\t}\t\t// 最常用的 Aware 接口 获取上下文对象\t\tif (bean instanceof ApplicationContextAware) {\t\t\t((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);\t\t}\t}
核心代码 这里可能生成代理类,是aop的入口
核心代码 非常重要 对类中某些特殊方法的调用,比如@PostConstruct,Aware接口ApplicationContextAwareProcessor 对Aware接口的调用如:EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware ApplicationContextAwareImportAwareBeanPostProcessor 对ImportAware的支持
调用一些Aware接口而已
核心方法 获取 field 上面的 @Resource 注解封装成对象 doWithLocalFields 循环查找
作用不大 走这里机会很小
FactoryBean<?> factory = (FactoryBean<?>) bean
ApplicationContextAwareProcessor 对 一些 Aware 接口的支撑
核心方法依赖注入
有、会优先实例化
从一级缓存获取bean 传提前暴露为true
ctors != null
可能发生do while循环 所以把 currElements集合所有元素 加入到 循环外层 elements 新容器
getMergedLocalBeanDefinition(beanName)
判断是不是实现了FactoryBean接口
TargetSource接口的运用,可以在用改一个类实现该接口,然后在里面定义实例化对象的方式,然后返回也就是说不需要 spring 帮助我们实例化对象这里可以直接返回实例本身这个代码不用看,实际开发过程中用不到
CommonAnnotationBeanPostProcessor处理 @Resource
return null
使用加载器加载类
smartSingleton.afterSingletonsInstantiated()
返回代理对象
dependsOn 不为空
没有
return result
bean instanceof FactoryBean
finishBeanFactoryInitialization(beanFactory);
实例化核心
while
return pf.getProxy(classLoader)
三级缓存加入的是一个lambda表达式
实例化核心流程
this.factoryBeanObjectCache.get(beanName)
删除三级缓存
((InitializingBean) bean).afterPropertiesSet()
核心方法 大部分走这里
升级到二级缓存
返回所有@Autowired 注解的构造函数
这两个收集注解过程到元数据Metadata和依赖注入populateBean方法一致。这里会收集后加入缓存,主要流程在 populateBean 记录
一级缓存
获取 bean类的所有构造方法
看父BeanFactory是否有
QualifierAnnotationAutowireCandidateResolver.getSuggestedValue(descriptor)
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName))
this.singletonFactories.get(beanName)
getCachedObjectForFactoryBean(beanName)
findAutowiredAnnotation(field)
实例化后调用方法 判断是否factoryBean
singletonObject = singletonFactory.getObject();
findLifecycleMetadata(bean.getClass())
根据 beanName 从缓存中拿实例
获取到 @Autowired 里面的required 方法的值 @Autowired有个 required 属性 默认为true
解析class类
是FactoryBean接口返回true 否则返回 false
寻找当前正在实例化的bean中有 @Autowired 注解的构造函数 beanPostProcessor应用
把 beanName 添加到 singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean 循环依赖用到这个容器
判断属性是否懒加载 @Lazy
从缓存里面拿 FactoryBean 类型的实例
拿到 InjectionMetadata 进行加入缓存
获取实例
调用Aware方法
afterSingletonCreation(beanName);
InstantiationAwareBeanPostProcessorAdapter
依赖注入过程 @Autowired @Resource 的支持CommonAnnotationBeanPostProcessor 支持 @ResourceAutowiredAnnotationBeanPostProcessor 支持 @Autowired
实例化用了 FactoryMethod 的方法
beanClass.getDeclaredConstructors()
Spring核心 BeanPostProcessor
通过构造方法实例化
获取@Value中的值,值类似于 ${student.name}
获取 Autowire metadata 元数据
强转为 FactoryBean 类从实现 FactoryBean 接口类中 调用getObject方法获取实例型
核心代码 对类中某些特殊方法的调用比如@PostConstruct,Aware接口
mbd.getDependsOn()
从正在创建的集合判断是否有bean正在创建,有则出现了循环依赖
添加三级缓存
直接返回实例本身
判断是否有有DependsOn
findAutowiredAnnotation(candidate)
判断 bean 是否实现了 FactoryBean 接口
获取class无参的构造函数
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName))
有注解的加入到容器 封装为ResourceElement
触发回调getBean函数
将带有 @Autowired 的属性 和 required值 封装成 AutowiredFieldElement 加入集合
this.singletonFactories.remove(beanName)
执行顺序 2
beanName 加上了前缀 FACTORY_BEAN_PREFIX = \"&\" 拿到的是类本身 不是getObject返回的
正在创建中的Bean集合
0 条评论
下一页