Browse Source

增加spring学习笔记:第20章:Spring 应用上下文生命周期

seamew 2 years ago
parent
commit
d1f711567a

+ 363 - 0
后端/Spring/spring源码学习/spring核心编程思想/20、Spring 应用上下文生命周期.md

@@ -0,0 +1,363 @@
+## 第二十章:Spring 应用上下文生命周期
+
+### ApplicationContext 接口继承关系
+
+![img](assets/o_201108090206ApplicationContext-16684235113772.png)
+
+### Spring 应用上下文生命周期
+
+- `AbstractApplicationContext#refresh`
+
+  ```java
+  @Override
+  public void refresh() throws BeansException, IllegalStateException {
+      synchronized (this.startupShutdownMonitor) {
+          // Prepare this context for refreshing.
+          prepareRefresh();
+  
+          // Tell the subclass to refresh the internal bean factory.
+          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
+  
+          // Prepare the bean factory for use in this context.
+          prepareBeanFactory(beanFactory);
+  
+          try {
+              // Allows post-processing of the bean factory in context subclasses.
+              postProcessBeanFactory(beanFactory);
+  
+              // Invoke factory processors registered as beans in the context.
+              invokeBeanFactoryPostProcessors(beanFactory);
+  
+              // Register bean processors that intercept bean creation.
+              registerBeanPostProcessors(beanFactory);
+  
+              // Initialize message source for this context.
+              initMessageSource();
+  
+              // Initialize event multicaster for this context.
+              initApplicationEventMulticaster();
+  
+              // Initialize other special beans in specific context subclasses.
+              onRefresh();
+  
+              // Check for listener beans and register them.
+              registerListeners();
+  
+              // Instantiate all remaining (non-lazy-init) singletons.
+              finishBeanFactoryInitialization(beanFactory);
+  
+              // Last step: publish corresponding event.
+              finishRefresh();
+          }
+  
+          catch (BeansException ex) {
+              if (logger.isWarnEnabled()) {
+                  logger.warn("Exception encountered during context initialization - " +
+                          "cancelling refresh attempt: " + ex);
+              }
+  
+              // Destroy already created singletons to avoid dangling resources.
+              destroyBeans();
+  
+              // Reset 'active' flag.
+              cancelRefresh(ex);
+  
+              // Propagate exception to caller.
+              throw ex;
+          }
+  
+          finally {
+              // Reset common introspection caches in Spring's core, since we
+              // might not ever need metadata for singleton beans anymore...
+              resetCommonCaches();
+          }
+      }
+  }
+  ```
+
+### Spring 应用上下文启动准备阶段
+
+- AbstractApplicationContext#prepareRefresh() 方法
+  - 启动时间 - `startupDate`
+  - 状态标识 - `closed(false)`、`active(true)`
+  - 初始化 PropertySources - initPropertySources()
+    - 默认为空方法,子类可继承
+    - Web 应用上下文继承这个方法,并将 Web 参数初始化为 `PropertySource`
+  - 检验 Environment 中必须属性
+    - `AbstractPropertyResolver#requiredProperties`,默认为空,可设置
+  - 初始化事件监听器集合
+    - `earlyApplicationListeners`
+    - `applicationListeners`
+  - 初始化早期 Spring 事件集合
+    - `earlyApplicationEvents`
+
+### BeanFactory 创建阶段
+
+- AbstractApplicationContext#obtainFreshBeanFactory 方法
+  - 抽象方法
+  - 子类实现,AbstractRefreshableApplicationContext#refreshBeanFactory
+    - 刷新 Spring 应用上下文底层 BeanFactory - refreshBeanFactory()
+      - 销毁或关闭 `BeanFactory` ,如果已存在的话
+      - 创建 BeanFactory - createBeanFactory()
+        - `DefaultListableBeanFactory`
+      - 设置 BeanFactory Id
+      - 自定义 `BeanFactory` 属性 - `customizeBeanFactory(beanFactory)`
+      - 设置 “是否允许 BeanDefinition 重复定义” - customizeBeanFactory(DefaultListableBeanFactory)
+        - `AbstractRefreshableApplicationContext#allowBeanDefinitionOverriding`
+        - 默认为 true
+        - 设置 “是否允许循环引用(依赖)” - customizeBeanFactory(DefaultListableBeanFactory)
+          - `AbstractRefreshableApplicationContext#allowCircularReferences`
+          - 默认为 true
+      - 加载 BeanDefinition - loadBeanDefinitions(DefaultListableBeanFactory) 方法
+        - 抽象方法
+      - 关联新建 `BeanFactory` 到 Spring 应用上下文
+- 返回 Spring 应用上下文底层 BeanFactory - getBeanFactory()
+  - 抽象方法
+
+### BeanFactory 准备阶段
+
+- AbstractApplicationContext#prepareBeanFactory(ConfigurableListableBeanFactory) 方法
+
+  - 关联 `ClassLoader`
+
+  - 设置 Bean 表达式处理器
+
+    - 与 SpEL 表达式相关
+    - `org.springframework.context.expression.StandardBeanExpressionResolver`
+
+  - 添加 PropertyEditorRegistrar 实现 - ResourceEditorRegistrar
+
+    - `org.springframework.beans.support.ResourceEditorRegistrar`
+
+  - 添加 Aware 回调接口 BeanPostProcessor 实现 - ApplicationContextAwareProcessor
+
+    - `EnvironmentAware`
+    - `EmbeddedValueResolverAware`
+    - `ResourceLoaderAware`
+    - `ApplicationEventPublisherAware`
+    - `MessageSourceAware`
+    - `ApplicationContextAware`
+
+  - 忽略 `Aware` 回调接口作为依赖注入接口
+
+  - 注册 ResolvableDependency 对象 - BeanFactory 、ResourceLoader 、 ApplicationEventPublisher 以及 Applicationcontext
+
+    - `BeanFactory` 是 `ApplicationContext` 关联的 `BeanFactory`
+    - `ResourceLoader`、`ApplicationEventPublisher` 以及 `Applicationcontext` 都是 `ApplicationContext`
+
+  - 添加 BeanPostProcessor - ApplicationListenerDetector
+
+    - 在 `BeanPostProcessor#postProcessAfterInitialization` 阶段,将单例的 `ApplicationListener` 加入 `ApplicationContext`
+
+  - 如果包含 beanName 是 loadTimeWeaver 的 bean,注册 BeanPostProcessor - LoadTimeWeaverAwareProcessor 对象,并设置容器的临时 ClassLoader
+
+    ,AbstractBeanFactory#tempClassLoader
+
+    - 与 AOP 相关
+
+  - 注册单例对象 - Environment、Java System Properties 以及 OS 环境变量
+
+    - `environment` - `ApplicationContext#environment`
+    - `systemProperties` - `(Map) System.getProperties()`
+    - `systemEnvironment` - `(Map) System.getenv()`
+
+### BeanFactory后置处理阶段
+
+- AbstractApplicationContext#postProcessBeanFactory(ConfigurableListableBeanFactory) 方法
+
+  - 由子类覆盖该方法
+
+- org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory) 方法
+
+  - 判断 BeanFactory 是不是 BeanDefinitionRegistry 的实例
+
+    - `DefaultListableBeanFactory` 实现 `BeanDefinitionRegistry`
+    - 如果是,调用 BeanFactoryPostProcessor 或 BeanDefinitionRegistryPostProcessor 后置处理方法
+      - `BeanDefinitionRegistryPostProcessor` 继承 `BeanFactoryPostProcessor`
+      - `BeanFactoryPostProcessor#postProcessBeanFactory`
+      - `BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry`
+    - 如果不是,只调用 `BeanFactoryPostProcessor` 后置处理方法 `BeanFactoryPostProcessor#postProcessBeanFactory`
+
+  - 如果包含 beanName 是 loadTimeWeaver 的 bean,注册 BeanPostProcessor - LoadTimeWeaverAwareProcessor 对象,并设置容器的临时 ClassLoader
+
+    ,AbstractBeanFactory#tempClassLoader
+
+    - 与 AOP 相关
+
+执行顺序:
+
+1. 对 BeanDefinitionRegistryPostProcessor 进行处理
+   1. 执行 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
+      1. 按照添加顺序执行, `AbstractApplicationContext#beanFactoryPostProcessors` 中的 `BeanDefinitionRegistryPostProcessor`
+      2. 按照 Order 顺序执行,`BeanFactory` 中实现了 `PriorityOrdered` 的 `BeanDefinitionRegistryPostProcessor` Bean
+      3. 按照 Order 顺序执行,`BeanFactory` 中实现了 `Ordered` 的 `BeanDefinitionRegistryPostProcessor` Bean
+      4. 按照 Order 顺序执行,其他 `BeanFactory` 中的 `BeanDefinitionRegistryPostProcessor` Bean
+   2. 执行 BeanFactoryPostProcessor#postProcessBeanFactory
+      1. `AbstractApplicationContext#beanFactoryPostProcessors` 中的普通 `BeanFactoryPostProcessor`
+      2. `BeanFactory` 中 `BeanDefinitionRegistryPostProcessor`
+2. 对 BeanFactoryPostProcessor 继续处理,BeanFactoryPostProcessor#postProcessBeanFactory
+   1. 按照 Order 顺序执行,实现 `PriorityOrdered` 接口的 `BeanFactoryPostProcessor`
+   2. 按照 Order 顺序执行,实现 `Ordered` 接口的 `BeanFactoryPostProcessor`
+   3. 其他常规 `BeanFactoryPostProcessor`
+
+### BeanFactory 注册 BeanPostProcessor 阶段
+
+- AbstractApplicationContext#registerBeanPostProcessors(ConfigurableListableBeanFactory) 方法
+  - 注册 `PriorityOrdered` 类型的 `BeanPostProcessor` Beans -- 该bean会提前初始化
+  - 注册 `Ordered` 类型的 `BeanPostProcessor` Beans
+  - 注册普通 `BeanPostProcessor` Beans
+  - 注册 MergedBeanDefinitionPostProcessor Beans
+    - `MergedBeanDefinitionPostProcessor` 继承 `BeanPostProcessor`,生命周期在 MergedBeanDefinition 后
+  - 重新注册 ApplicationListenerDetector 对象
+    - 为了将 `ApplicationListenerDetector` 的顺序放到最后
+
+### 初始化內建 Bean: MessageSource
+
+- AbstractApplicationContext#initMessageSource 方法
+  - 如果 `BeanFactory` 中存在 beanName 为 `messageSource` 的 `MessageSource` ,则使用,否则注册 `DelegatingMessageSource`
+  - 回顾章节 - 第十二章 Spring 国际化 - `MessageSource` 内建依赖
+
+### 初始化內建 Bean: Spring 事件广播器
+
+- AbstractApplicationContext#initApplicationEventMulticaster 方法
+  - 如果 `BeanFactory` 中存在 beanName 为 `applicationEventMulticaster` 的 `ApplicationEventMulticaster` ,则使用,否则注册 `SimpleApplicationEventMulticaster`
+  - 回顾章节 - 第十七章 Spring 事件 - `ApplicationEventPublisher` 底层实现
+
+### Spring 应用上下文刷新阶段
+
+- AbstractApplicationContext#onRefresh 方法
+  - 空方法,由子类覆盖该方法
+    - `org.springframework.web.context.support.AbstractRefreshableWebApplicationContext#onRefresh`
+    - `org.springframework.web.context.support.GenericWebApplicationContext#onRefresh`
+    - `org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext#onRefresh`
+    - `org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#onRefresh`
+    - `org.springframework.web.context.support.StaticWebApplicationContext#onRefresh`
+
+### Spring 事件监听器注册阶段
+
+- AbstractApplicationContext#registerListeners 方法
+  - 将 ApplicationListener 添加到 AbstractApplicationContext#applicationEventMulticaster
+    - 添加当前应用上下文所关联的 `ApplicationListener` 对象(集合)
+    - 添加 `BeanFactory` 所注册 `ApplicationListener` Beans
+  - 广播早期 Spring 事件
+    - `AbstractApplicationContext#earlyApplicationEvents`
+
+### BeanFactory 初始化完成阶段
+
+- AbstractApplicationContext#finishBeanFactoryInitialization(ConfigurableListableBeanFactory) 方法
+
+  - `BeanFactory` 关联 `ConversionService` Bean,如果存在
+
+    - beanName 为 `conversionService` 的 `ConversionService`
+
+  - 添加 `StringValueResolver` 对象
+
+    - 如果 `AbstractBeanFactory#embeddedValueResolvers` 为空,添加一个
+
+      ```java
+      if (!beanFactory.hasEmbeddedValueResolver()) {
+      	beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
+      }
+      ```
+
+  - 依赖查找 `LoadTimeWeaverAware` Bean -- AOP
+
+  - `BeanFactory` 临时 `ClassLoader` 置为 `null`
+
+  - `BeanFactory` 冻结配置
+
+    - `DefaultListableBeanFactory#configurationFrozen`
+    - `DefaultListableBeanFactory#frozenBeanDefinitionNames`
+
+  - `BeanFactory` 初始化非延迟单例 Beans
+
+    1. 初始化非延迟单例 Bean
+    2. 触发单例 Bean 中的 `SmartInitializingSingleton` 的生命周期, `SmartInitializingSingleton#afterSingletonsInstantiated`
+
+### Spring 应用上下文刷新完成阶段
+
+- AbstractApplicationContext#finishRefresh 方法
+  - 清除 `ResourceLoader` 缓存 - `clearResourceCaches()` @since 5.0
+  - 初始化 LifecycleProcessor 对象 - initLifecycleProcessor()
+    - 如果不存在 beanName 为 `lifecycleProcessor` 的 `LifecycleProcessor`,则使用 `DefaultLifecycleProcessor`
+  - 调用 `LifecycleProcessor#onRefresh()` 方法
+  - 发布 Spring 应用上下文已刷新事件 - `ContextRefreshedEvent`
+  - 向 `MBeanServer` 托管 Live Beans
+
+### Spring 应用上下文启动阶段
+
+- AbstractApplicationContext#start() 方法
+  - 启动 LifecycleProcessor
+    - 依赖查找 `Lifecycle` Beans
+    - 启动 `Lifecycle` Beans
+- 发布Spring应用上下文已启动事件 - `ContextStartedEvent`
+
+### Spring 应用上下文停止阶段
+
+- AbstractApplicationContext#stop() 方法
+  - 停止 `LifecycleProcessor`
+  - 依赖查找 `Lifecycle` Beans
+  - 停止 `Lifecycle` Beans
+- 发布 Spring 应用上下文已停止事件 - `ContextStoppedEvent`
+
+### Spring 应用上下文关闭阶段
+
+- `AbstractApplicationContext#close()` 方法
+- 状态标识:`active(false)`、`closed(true)`
+- Live Beans JMX 撤销托管
+  - `LiveBeansView#unregisterApplicationContext(ConfigurableApplicationContext)`
+- 发布 Spring 应用上下文已关闭事件 - `ContextCLosedEvent`
+- 关闭 LifecycleProcessor
+  - 依赖查找 `Lifecycle` Beans
+  - 停止 `Lifecycle` Beans
+- 销毁 Spring Beans
+- 关闭 `BeanFactory`
+- 回调 `onClose()`
+- 注册 Shutdown Hook 线程(如果曾注册)
+
+## 面试题
+
+#### Spring 应用上下文生命周期有哪些阶段?
+
+- 刷新阶段 - `ConfigurableApplicationContext#refresh()`
+- 启动阶段 - `ConfigurableApplicationContext#start()`
+- 停止阶段 - `ConfigurableApplicationContext#stop()`
+- 关闭阶段 - `ConfigurableApplicationContext#close()`
+
+#### Spring 应用上下文生命周期执行动作?
+
+## 课程加餐内容讨论
+
+### 为什么说 ObjectFactory 提供的是延迟依赖查找?
+
+- 原因
+  - `ObjectFactory` (或 `ObjectProvider` )可关联某一类型 Bean
+  - `ObjectFactory` 和 `ObjectProvider` 对象在被依赖注入和依赖查询时并未实时查找关联类型的 Bean
+  - `ObjectFactory` (或 `ObjectProvider` )调用 `getObject()` 方法时,目标 Bean 才被依赖查找
+- 总结
+  - `ObjectFactory` (或 `ObjectProvider` )相当于某一类型 Bean 依赖查找代理对象
+
+### 依赖查找(注入)的Bean会被缓存吗?
+
+- 单例 Bean (Singleton) - 会
+  - 缓存位置:`org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#singletonObjects` 属性
+- 原型 Bean (Prototype) - 不会
+  - 当依赖查询或依赖注入时,根据 `BeanDefinition` 每次创建
+- 其他 Scope Bean
+  - request : 每个 ServletRequest 内部缓存,生命周期维持在每次HTTP请求
+  - session : 每个 HttpSession 内部缓存,生命周期维持在每个用户HTTP会话
+  - application : 当前 Servlet 应用内部缓存
+
+#### @Bean 的处理流程是怎样的?
+
+- 解析范围 - Configuration Class 中的 `@Bean` 方法
+- 方法类型 - 静态 `@Bean` 方法和实例 `@Bean` 方法
+
+#### BeanFactory是如何处理循环依赖的?
+
+- 循环依赖开关(方法)- `AbstractAutowireCapableBeanFactory#setAllowCircularReferences`
+- 单例工程(属性)- `DefaultSingletonBeanRegistry#singletonFactories`
+- 获取早期未处理 Bean (方法)- `AbstractAutowireCapableBeanFactory#getEarlyBeanReference`
+- 早期未处理 Bean (属性)- `DefaultSingletonBeanRegistry#earlySingletonObjects`
+
+#### MyBatis 与 Spring Framework 是如何集成的?

BIN
后端/Spring/spring源码学习/spring核心编程思想/assets/o_201108090206ApplicationContext-16684235113772.png


BIN
后端/Spring/spring源码学习/spring核心编程思想/assets/o_201108090206ApplicationContext.png


+ 41 - 5
部署文档/云平台/安装云平台环境.md

@@ -592,7 +592,7 @@ kubectl -n kubesphere-system patch svc ks-apiserver -p '{"spec":{"type":"NodePor
 
 ## 5.6、创建云平台的企业空间
 
-1. 登录kubesphere,输入http://10.168.59.60:30880/,端口号默认为30880,第一次进入需要修改初始密码
+1. 登录kubesphere,输入http://10.168.59.60:30880/,端口号默认为30880,第一次进入需要修改初始密码为: MKcloud123
 ![image-20211115214619362](assets/image-20211115214619362.png)
 2. 进入企业空间,创建新的企业空间为mkcloud
 ![image-20211115214723424](assets/image-20211115214723424.png)
@@ -614,11 +614,47 @@ kubectl -n kubesphere-system patch svc ks-apiserver -p '{"spec":{"type":"NodePor
 4. 添加成功会显示私有密钥
 ![image-20211118211733125](assets/image-20211118211733125.png)
 
-# 6、目前遇见的BUG与解决方案
+# 6、卸载云平台环境
 
 ***
 
-## 6.1、harbor仓库登录显示400错误
+## 6.1、卸载K8S
+
+```shell
+kubeadm reset -f
+modprobe -r ipip
+lsmod
+rm -rf ~/.kube/
+rm -rf /etc/kubernetes/
+rm -rf /etc/systemd/system/kubelet.service.d
+rm -rf /etc/systemd/system/kubelet.service
+rm -rf /usr/bin/kube*
+rm -rf /etc/cni
+rm -rf /opt/cni
+rm -rf /var/lib/etcd
+rm -rf /var/etcd
+yum clean all
+yum remove kube*
+```
+
+## 6.2、卸载docker
+
+```shell
+# 1.停止docker
+sudo systemctl stop docker
+# 2.查询安装过的包
+yum list installed | grep docker
+# 3.删除安装的软件包
+yum -y remove docker*
+# 4.删除镜像/容器等
+rm -rf /var/lib/docker
+```
+
+# 7、目前遇见的BUG与解决方案
+
+***
+
+## 7.1、harbor仓库登录显示400错误
 
 ![image-20211123200112617](assets/image-20211123200112617.png)
 ```sh
@@ -650,7 +686,7 @@ docker ps
 docker restart e39629e9c2c4
 ```
 
-## 6.2、单节点安装pod报错Pending
+## 7.2、单节点安装pod报错Pending
 
 ![image-20220317164430599](assets/image-20220317164430599.png)
 
@@ -659,7 +695,7 @@ docker restart e39629e9c2c4
 kubectl taint nodes --all node-role.kubernetes.io/master-
 ```
 
-## 6.3、kubesphere的api-server无法启动
+## 7.3、kubesphere的api-server无法启动
 
 api-server显示报错---无法申请资源,原因是docker的进程数不够,增加一下的配置重启docker就行