创建Bean
2022-06-05 13:10:20 0 举报
AI智能生成
Spring 创建 Bean 源码分析
作者其他创作
大纲/内容
获取 beanName
如果是 &xxx,则去掉&
如果是别名找到真正的 beanName
从缓存中查询
先从一级缓存 singletonObjects 找
- 如果没找到并且正在创建(singletonsCurrentlyInCreation)的话 从二级缓存(earlySingletonObjects)查找
如果二级缓存中没找到并且允许循环依赖的话去三级缓存查找(singletonFactories)如果找到的话直接调用 ObjectFactory#getObject 获取代理对象或原始对象
如果已经在单例池中直接返回 getObjectForBeanInstance
如果 name 不是工厂引用(&xxx)直接返回
如果是工厂 Bean,先从 factoryBeanObjectCache 获取
如果没拿到则创建工厂 Bean
获取合并的BeanDefinition
(此处目的是判断要不要执行后置处理器,应用程序自身创建的不执行)
(此处目的是判断要不要执行后置处理器,应用程序自身创建的不执行)
如果没有父 BeanDefinition 直接深拷贝得到 RootBeanDefinition
如果有递归合并父 BeanDefinition 得到 RootBeanDefinition
放入 mergedBeanDefinitions 缓存
调用 FactoryBean#getObject() 创建 Bean
执行 BeanPostProcessor#postProcessAfterInitialization( ) (工厂 Bean执行 初始化后)
如果是单例,放入缓存 factoryBeanObjectCache.put(beanName, object)
如果单例池中不存在则去创建
判断 beanName 在不在当前 beanFactory,不在则去父 beanFactory 中找
标记为已经创建放入 alreadyCreated 中,同时会清理掉 MergedBeanDefinition(防止元数据变化)
获取 mergedBeanDefinition
检查 BeanDefinition 是不是抽象的,抽象的无法实例化
创建 dependsOn 的 Bean
判断是否循环依赖,如果是则报错
缓存依赖关系,销毁 Bean 之前先销毁依赖 Bean(缓存我依赖了谁,谁依赖了我)
创建依赖 Bean
根据不同的作用域分别创建
单例
标记正在创建,加入 singletonsCurrentlyInCreation
调用 AbstractBeanFactory#createBean( ) 创建 Bean
加载类,将类加载为 class 对象
将 class 对象赋值给 BeanDefinition 的 beanClass
实例化前 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
遍历执行所有 postProcessBeforeInstantiation
如果其中一个有返回值则不在执行其余的,并且会执行 postProcessAfterInitialization (初始化后 AOP)直接返回
实例化 doCreateBean( )
实例化 (包括推断构造)AbstractAutowireCapableBeanFactory#createBeanInstance
判断是否通过 Supplier 创建 Bean
判断是否通过工厂方法(@Bean)创建 Bean
如果构造过了,那就调用 autowireConstructor() 构造一个对象
推断构造 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
查找 @Lookup 注解的方法
如果存在可用的构造方法,或者当前 BeanDefinition 的 autowired 是 AUTOWIRE_CONSTRUCTOR,或者 BeanDefinition 中指定了构造方法参数值,或者创建 Bean 的时候指定了构造方法参数值,那么就调用 autowireConstructor()
否则通过无构造方法实例化
处理 @Lookup 注解
如果 @lookup 指定了 beanName ,用指定的名字在容器中取 Bean,否则通过方法返回类型获取 Bean
BeanDefinition 的后置处理 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
@Autowired 查找注入点
遍历属性
是否被 @Autowired 、@value、@inject 注解
判断是否是静态属性,如果是则不是注入点
判断是否必须注入
封装成 AutowiredFieldElement 进行缓存
遍历方法
判断是否是桥接方法,如果是则不是注入点
是否被 @Autowired 、@value、@inject 注解
判断是否是静态属性,如果是则不是注入点
判断是否必须注入
封装成 AutowiredMethodElement 进行缓存
@Resource 查找注入点
遍历属性
筛选 @Resource 注解的属性
如果是静态属性则直接抛出异常
将属性信息封装成 ResourceElement
遍历方法
过滤桥接方法
过滤@Resource 注解的方法
如果是静态的方法则直接抛出异常
如果参数不是一个抛出异常
将方法信息封装成 ResourceElement
加入三级缓存(为了解决循环依赖)
填充属性
实例化后 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
查找自动注入的 Bean(Spring 自带的自动注入)(只是查找并未赋值)
spring 自带自动注入
根据 name 注入
获取需要注入的属性名
遍历并获取 Bean 对象,然后设置到 pvs
记录相互依赖关系
根据 type 注入
获取需要注入的属性名
根据属性名获取属性描述
属性类型为 Object 则不进行注入
更具类型获取 bean 对象,然后设置到 pvs
记录相互依赖关系
填充属性后 InstantiationAwareBeanPostProcessor#postProcessPropertyValues
@Autowired 属性注入
字段注入
封装成 DependencyDescriptor
获取类型装换器
从 beanFactory 中查找匹配的 Bean 对象 resolveDependency
初始化入参获取器
匹配类型为 Optional,将 doResolveDependency 结果包装成 Optional
如果是 ObjectFactory 或者 ObjectProvider,则生成一个 DependencyObjectProvider 对象,在 getBean 时调用
如果依赖描述上右 @Lazy 注解,则生成一个代理对象返回,在调用代理对象的方法时调用 doResolveDependency
不是以上情况则直接调用 doResolveDependency
处理 @Value 注解
获取注解指定的值
如果指定的值是 String 类型
处理占位符填充 ${}
处理 Spring 表达式 #{}
将 value 转换为 typeConverter 所对应的类型
如果依赖注入的类型是数组、集合等,找出所有匹配的 Bean 返回
findAutowireCandidates( ) 根据类型找到所有 Bean 添加到 map,key 是 beanName,value 有可能是 bean 对象,有可能是 beanClass
从 BeanFactory 中找出和 requiredType 匹配的 beanName
根据类型从 resolvableDependencies 中匹配 Bean
遍历匹配到的 BeanName ,不是自己注入自己并且通过检查则加入 候选
SimpleAutowireCandidateResolver#isAutowireCandidate() 检查 BeanDefinition 的 autowireCandidate 属性是不是为 true
GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate 检查 BeanDefinition 的 beanClass 属性和当前注入点的 type 是否匹配(包括泛型类型校验)
QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate()检查 BeanDefiniton 的 qualifier 属性和注入点的 qualifer 属性是否匹配
遍历完之后候选为空,判断是否需要注入自己
如果匹配到 0 个,判断是否必须注入,如果是则抛出异常
如果匹配到多个进行筛选 @Primary -->优先级最高 --》name
如果没实例化则进行实例化
缓存找到的对象 (缓存在注入点中,原型 Bean 第二次创建 Bean 时会触发缓存,缓存的是 BeanName 并不是 Bean 对象,防止注入点为原型而注入同一个对象)
通过反射给 field 赋值
方法注入
如果 pvs 中已经有了当前注入对象的示例,则跳过注入
获取方法参数所有类型
遍历所有参数类型,将每个参数和方法信息封装成 MethodParameter 对象,然后再封装成 DependencyDescriptor
调用 BeanFactory 的 resolveDependency() 方法查找匹配的 Bean 对象
缓存匹配到的 bean
通过反射执行方法
@Resource 属性注入
如果 @Resource 没有指定名字,并且 beanFactory 中不存在默认名字对应的 Bean,则根据类型查找(和 @Autowired 一致)
若果指定名字或者 BeanFactory 中包含默认名字的 Bean,直接根据名字获取
注入 spring 自带自动注入的 bean 和 手动注入的 bean
初始化
执行 Aware(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
初始化前 BeanPostProcessor#postProcessBeforeInitialization (@PostConstruct 、其他 Aware 回调)
初始化 (InitializingBean#afterPropertiesSet、自定义 init 方法)
初始化后 BeanPostProcessor#postProcessAfterInitialization
AOP:AbstractAutoProxyCreator#postProcessAfterInitialization
如果之前存在循环依赖,则已经进行过 AOP ,不在进行
如果之前存在循环依赖,则已经进行过 AOP ,不在进行
注册销毁 Bean
不是原型 Bean
需要销毁
hasDestroyMethod
实现 DisposableBean
实现 AutoCloseable
有自定义销毁方法
通过 DestructionAwareBeanPostProcessor.requiresDestruction(bean) 判断
移除正在创建标志,从 singletonsCurrentlyInCreation 中移除
添加到单例池
原型
在 prototypesCurrentlyInCreation 中标记创建
直接调用 AbstractAutowireCapableBeanFactory#createBean
清除标记
其他
判断作用域是否注册了
其余和原型类似,只是先会在缓存中拿,不存在再创建并进行缓存
如果需要类型校验则进行类型校验然后返回
0 条评论
下一页