标签:模式 mamicode ash 接口 类重写 rap find factory spring容器
Prepare this context for refreshing.
刷新前的预处理
表示在真正做refresh操作之前需要准备做的事情:
1. 设置Spring容器的启动时间,
2. 开启活跃状态,撤销关闭状态
3. 验证环境信息里一些必须存在的属性等
// 清空数据
//Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
获取BeanFactory;默认实现是DefaultListableBeanFactory
加载BeanDefition 并注册到 BeanDefitionRegistry
实例化 DefaultListableBeanFactory
设置序列化id
自定义bean工厂的一些属性(只有两个配置:是否覆盖、是否允许循环依赖)
加载(读取并注册)应用中的BeanDefinitions :
loadBeanDefinitions(beanFactory) :读取applicationContext.xml这样的自定义的及默认的bean配置,并注册到this.beanDefinitionMap里
BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器等),classloader& post-processor
BeanFactory准备工作完成后进行的后置处理工作
直接运行好像没有调用的。给第三方用的吧。
实例化并调用所有已注册的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
初始化MessageSource组件(做国际化功能;消息绑定,消息解析)bean:messageSource
初始化事件派发器 bean:applicationEventMulticaster
空实现。子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
注册实现ApplicationListener接口的bean
实例化所有单例bean
把ConversionService
注册属性处理器PropertyResolver默认StringValueResolver
beanFactory.preInstantiateSingletons(); 实例化所有立即加载的单例bean
step1:从缓存中获取bean
准备生成iBbean先查询是否已创建或正在创建该bean(上面5.invokeBeanFactoryPostProcessors(beanFactory);已经构建了部分的bean)
用了singletonsCurrentlyInCreation Set存储正在创建的bean,这里没有开始创建,所以这里没有进if判断。
step2 : 标记未正在创建
this.alreadyCreated.add(beanName);
step3: 开始创建bean
step 3.1:
this.singletonsCurrentlyInCreation.add(beanName) 把A添加到正在创建的map中
调用A的()→ getObject() lambda函数
这里是处理的逻辑
step 3.2: doCreateBean真正的创建bean
先创建简单bean(只调用构造器)
AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition 找到需要autowired的值, dowithLocalfields 和 dowithlocalmethods ,封装返回new InjectionMetadata(clazz, elements)
放入三级缓存中this.singletonFactories.put(beanName, singletonFactory); 前提如果允许循环依赖且bean是单例模式 ,getEarlyBeanReference —> 第三个入参就是对应的简单bean。
开始属性填充populateBean
调用AutowiredAnnotationBeanPostProcessor#postProcessProperties
上面已经拿到了需要装配的信息,这里findAutowiringMetadata直接能从缓存this.injectionMetadataCache中拿到
准备注入bean B
B 封装成 DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
处理依赖org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency
这里matchingBeans只获取到了lagouBean(单个bean和多个bean的操作不一样,后面再看看)
后面回到了
org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate
—> org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
—>org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
初始化构造器之后,populatebean, 处理lagoubean的依赖itBean ,从各级缓存中获取bean,org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean), 此时可以把itBean从三级缓存this.singletonFactories中放到二级缓存this.earlySingletonObjects中
itBean —> this.earlySingletonObjects
lagouBean —> this.earlySingletonObjects
lagouBean注入itBean
populateBean后 调用初始化方法,应用BeanPostProcessor后置处理器
开始第二次earlySingletonExposure判断,从缓存获取getSingleton,但是此时不允许循环引用(只能从1,2级缓存中拿bean 主要原因为不允许bean在上面初始化后被改变)
getSingleton afterSingletonCreation 把singletonsCurrentlyInCreation中删除lagouBean
getSingleton addSingleton(beanName, singletonObject);
此时lagouBean初始化完成。
itBean —> this.earlySingletonObjects
lagouBean —> this.singletonObjects
返回的结果在这里inject
itBean populate完成,后面操作和lagouBean操作一致。最终到下面的步骤
getSingleton addSingleton(beanName, singletonObject);
此时lagouBean初始化完成。
itBean —> this.earlySingletonObjects
lagouBean —> this.singletonObjects
初始化所有的bean完成,通知
org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated
1.clearResourceCaches();
清除资源缓存
2.initLifecycleProcessor();
lifecycleProcessor加入到this.singletonObjects
3.getLifecycleProcessor().onRefresh();
第二步的lifecycle刷新
4.publishEvent(new ContextRefreshedEvent(this));
发布事件
5.LiveBeansView.registerApplicationContext(this);
标签:模式 mamicode ash 接口 类重写 rap find factory spring容器
原文地址:https://www.cnblogs.com/dinry/p/14854298.html