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