Spring中bean的实例化流程
2020-08-27 15:09:59 0 举报
Spring的bean实例化流程
作者其他创作
大纲/内容
refresh()
把beanName添加到singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean
2、判断2级缓存中是否有该实例,有则返回该实例
1、this.singletonObjects.get(beanName)
重点知识:BeanDefinition中factoryMethodName属性不为空,只有两种情况。第一,在<bean>标签中配置factoryMethod属性,第二,用@Bean注解修饰的方法,@Bean注解修饰的方法,spring扫描到这个注解时就会创建一个新的beanDefinition对象,并且把方法名称设置到对象中的factoryMethodName中
调用Aware接口方法
AutowiredAnnotationBeanPostProcessor
((ImportAware) bean).setImportMetadata(importingClass)
singletonFactory.getObject()
finishBeanFactoryInitialization(beanFactory)
如果缓存中没有该实例,则要创建该实例
调用实现了Aware接口的方法
1、getSingleton(beanName)
AOP的入口生成代理实例
1、@Bean注解的实例化
AbstractAutoProxyCreator
AnnotationConfigApplicationContext
CommonAnnotationBeanPostProcessor
2、有参构造函数的实例化
findLifecycleMetadata(beanType)
if (earlySingletonExposure)
5、bean实例化完成后的操作
DisposableBean接口
3、判断3级缓存中是否有该实例,有则返回该实例,并把从3级缓存获取到的实例设置到2级缓存中
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||\t\t\t\tmbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))
如果该实例实现了FactoryBean接口,先从缓存中获取实例
1、创建实例还没进行IOC依赖注入
循环beanDefinitionNames,调用getBean方法实例化每一个bean,每一个类的时候都会调用到getBean方法
标签的destory方法
6、注册单例bean的销毁
创建实例
ImportAwareBeanPostProcessor
refresh方法是spring启动的核心方法
源码入口
buildAutowiringMetadata(clazz)
bean实例化核心逻辑
((DisposableBean) this.bean).destroy()
调用@PostConstruct注解的方法
ImportAware
如果实现了FactoryBean接口,并且缓存中没有该实例,调用FactoryBean的getObject方法获取实例
@Resource的依赖注入
收集@PostConstruct,@PreDestroy
重点知识:这里是bean实例化完成后的操作,其中InitializingBean,afterPropertiesSet()方法是比较重要的接口和方法
if (mbd.isSingleton())
4、bean的IOC依赖注入
重点知识:这里是一个BeanPostProcessor接口的运用,获取有参的构造函数或者获取构造函数上有@Autowired注解的构造函数。对应的处理类为:AutowiredAnnotationBeanPostProcessor
ApplicationContextAwareProcessor
3、无参构造函数的实例化,这里直接就是反射实例化
重点知识:FactoryBean接口是spring中一个比较重要的接口,很多框架都会实现这个接口来实现该接口中的getObject方法,在getObject方法中可以自己来定义类的实例化过程,当spring调用getObject方法时就会把我们自己创建的实例交由spring来管理
如果缓存中能获取到实例
重点知识:只有允许提前暴露的情况下才会在singletonFactories容器中设置一个三级缓存,并且只有在存在单例实例的循环依赖的情况下才会调到这个三级缓存的getObject方法从三级缓存的对象工厂中获取到该实例。
重点知识:这里根据前面收集的bean中的注解来进行ioc依赖注入,只有属性或者方法上面有@Autowired、@Resource、@Value注解的才会进行ioc依赖注入,依赖注入又是BeanPostProcessor接口的运用
factory.getObject()
2、this.earlySingletonObjects.get(beanName)
invokeCustomDestroyMethod(this.destroyMethod)
this.factoryBeanObjectCache.get(beanName)
getBean(beanName)
((InitializingBean) bean).afterPropertiesSet()
重点知识:判断bean是否有切面,如果有切面则生成bean的代理
重要创建bean的逻辑
重点知识:这里是进行Bean的ioc依赖注入之前做的注解收集工作,简单来说就是收集bean中哪些属性或者哪些方法上面有相应的注解,在ioc或者实例化完成后进行相应的操作
这里调用了某些Aware接口和有@PostConstruct注解的方法
@Autowired、@Value的依赖注入
buildResourceMetadata(clazz)
beanFactory.preInstantiateSingletons()
收集@Resource
如果能收集到有参构造函数
从单例池中获取实例
InitializingBean接口,afterPropertiesSet
3、singletonFactory.getObject()
重点知识:找到前面收集的@Autowired@Value的属性或者方法
init-method
重点知识:这里就是根据前面收集的属性或者方法上面的注解进行了反射依赖注入属性,但是这里要注意,依赖注入的属性值如果是应用数据类型,在这里会触发该属性的getBean操作,就是会通过getBean方法获取属性的值
找前面收集的注解
如果这里有返回值,就代表这个bean已经结束创建了,已经完全创建成功
1、getCachedObjectForFactoryBean(beanName)
beforeSingletonCreation(beanName)
反射调用方法
buildLifecycleMetadata(clazz)
if (mbd.getFactoryMethodName() != null)
设置三级缓存
@PreDestroy执行
afterPropertiesSet()
反射实例化
3、是否允许提前暴露
1、判断1级缓存中是否有实例,有则返回该实例
findLifecycleMetadata(bean.getClass())
InitDestroyAnnotationBeanPostProcessor

收藏

收藏
0 条评论
下一页