isle-sofa-boot模块隔离
初始化
- 初始化SOFABoot模块:主要是初始化各模块的SpringContext上下文
- 如基于多Ark Biz启动,一般不会包含此包,各Biz间通信基于runtime-sofa-boot包完成
Spring启动完成后广播事件
- Spring相关
1 | // AbstractApplicationContext.java,参考[spring-ioc-src.md#refresh方法概览](/_posts/java/java-src/spring-ioc-src.md#refresh方法概览) |
- SofaModuleContextRefreshedListener.java 监听Spring启动后事件
1 | // SofaModuleContextRefreshedListener实例化参考[sofa-boot-autoconfigure](#sofa-boot-autoconfigure) |
处理pipeline流水线
- DefaultPipelineContext.java, 其实例化参考sofa-boot-autoconfigure
1 | public class DefaultPipelineContext implements PipelineContext { |
SpringContextInstallStage为例
1 | // AbstractPipelineStage.java |
创建模块的SpringContextLoader(上下文加载器)
- SpringContextInstallStage.java
1 | protected SpringContextLoader createSpringContextLoader() { |
- DynamicSpringContextLoader.java解析spring配置文件,加载Bean。下文加载SpringContext配置文件会调用
1 | public class DynamicSpringContextLoader implements SpringContextLoader { |
加载SpringContext配置文件
- SpringContextInstallStage.java
1 | // 加载SpringContext配置文件 |
- AbstractDeploymentDescriptor.java
1 | public abstract class AbstractDeploymentDescriptor implements DeploymentDescriptor { |
- FileDeploymentDescriptor.java 基于文件安装的模块,另外一个实现是基于Jar(JarDeploymentDescriptor)
1 | public class FileDeploymentDescriptor extends AbstractDeploymentDescriptor { |
并行刷新SpringContext
- SpringContextInstallStage.java
1 | private void refreshSpringContextParallel(ApplicationRuntimeModel application) { |
runtime-sofa-boot
- runtime-sofa-boot-starter-3.1.4.jar
初始化
- 基于SofaBoot的简单模块隔离,或者基于多Ark Biz启动,都会用到此包
- 主要是管理组件(Component, 本质是Bean/服务. 包括ReferenceComponent,ServiceComponent,SpringContextComponent)生命周期
- 组件管理类ComponentManagerImpl
- register/registerAndGet 注册组件
- 服务端Biz, 其Spring初始化时调用,如:ServiceFactoryBean(通过扫描含@SofaReference注解的Bean)、ExtensionFactoryBean
- 服务端基于API初始化时调用:ServiceClientImpl、ExtensionClientImpl
- 客户端Biz初始化@SofaReference应用,ReferenceRegisterHelper
- ReferenceFactoryBean(InitializingBean)
- ReferenceAnnotationBeanPostProcessor(BeanPostProcessor)
- ReferenceClientImpl 客户端基于API注册引用
- register/registerAndGet 注册组件
- Spring初始化时,会调用其 postProcessBeforeInitialization 方法
- 如根据
@SofaReference
注解,将组件信息(此时为ReferenceComponent类)保存到ComponentManagerImpl#registry集合中,集合中的key为ComponentName类型- 此时ComponentName如:
reference:com.alipay.sofa.isle.sample.SampleJvmService:#2120635923
(reference表示基于此注解解析的引用信息,会创建其代理对象)
- 此时ComponentName如:
- 如根据
@SofaService
注解,将组件信息(此时为ServiceComponent类)保存到registry集合中
- 如根据
BeanPostProcessor注册组件入口
ReferenceAnnotationBeanPostProcessor为例
- ReferenceAnnotationBeanPostProcessor.java
1 | public class ReferenceAnnotationBeanPostProcessor implements BeanPostProcessor, PriorityOrdered { |
- ReferenceRegisterHelper.java
1 | public class ReferenceRegisterHelper { |
ServiceBeanFactoryPostProcessor为例
- ServiceBeanFactoryPostProcessor.java 修改(Component)Bean的定义
1 | public class ServiceBeanFactoryPostProcessor implements BeanFactoryPostProcessor { |
- AbstractContractFactoryBean.java 触发Component注册
1 | public abstract class AbstractContractFactoryBean implements InitializingBean, FactoryBean, |
- ServiceFactoryBean.java
- 同理还有ReferenceFactoryBean
1 | public class ServiceFactoryBean extends AbstractContractFactoryBean { |
组件即其生命周期
- Component接口,组件级别,可以理解为一个服务类相关信息
- 方法:register、unregister、resolve、unresolve、activate、deactivate、exception
- 子接口:ComponentInfo,主要需要提供getType、getName等功能
- 抽象类:AbstractComponent,主要是实现 ComponentInfo,减少代码量
- 对应实现如:SpringContextComponent(类型为Spring)、ServiceComponent(类型为service)、ReferenceComponent(类型为reference)
1 | /** |
ComponentManagerImpl
组件管理者(基于组件类维度)
1 | public class ComponentManagerImpl implements ComponentManager { |
激活组件
ReferenceComponent为例
1 | public class ReferenceComponent extends AbstractComponent { |
- JvmBindingAdapter.java
1 | public class JvmBindingAdapter implements BindingAdapter<JvmBinding> { |
ServiceComponent为例
- 初始化模块的时候会调用,参考下文并行刷新SpringContext
1 | public class ServiceComponent extends AbstractComponent { |
SpringContextComponent为例
- sofa v3.6.0才有
- 初始化模块的时候会调用,参考下文并行刷新SpringContext
1 | public class SpringContextComponent extends AbstractComponent { |
扩展点初始化
- 入口
1 | // AbstractExtFactoryBean => CommonContextBean -> InitializingBean |
sofa-boot-autoconfigure
- spring.factories
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ |
- SofaModuleAutoConfiguration.java
1 |
|
Ark容器启动流程
- 参考:https://www.sofastack.tech/projects/sofa-boot/sofa-ark-startup/
流程图
- SofaArk相关常量参考
com.alipay.sofa.ark.spi.constant.Constants
sofa-ark-support-starter
- 启动Ark入口
- ArkApplicationStartListener.java 监听类
1 | // spring.factories声明此类 |
- SofaArkBootstrap.java
1 | public class SofaArkBootstrap { |
sofa-ark-container
ArkContainer
- ArkContainer.java
1 | public class ArkContainer { |
以DeployBizStage为例(执行Biz的main方法)
- DeployBizStage.java
1 |
|
- BizDeployServiceImpl.java
1 |
|
- DefaultBizDeployer.java
1 |
|
- BizModel.java
1 | public class BizModel implements Biz { |
启动Biz的服务
- 上文mainMethodRunner.run()会调用各Biz的SpringBootApplication.main方法,从而相当于启动一个SpringBoot项目。那么Spring项目启动则势必会调用到refresh方法,最终触发此处onRefresh(refresh - finishRefresh - onRefresh)方法,从而初始化Tomcat
- refresh过程还会刷新SofaBoot Component(如ReferenceComponent,即@SofaReference等注解)的生命周期,参考runtime-sofa-boot
- ServletWebServerApplicationContext.java
1 | // org.springframework.boot.web.servlet.context |
- ArkTomcatServletWebServerFactory.java
1 | // sofa-ark-springboot-starter-1.1.5.jar |
- ArkTomcatWebServer
1 | public class ArkTomcatWebServer implements WebServer { |
Biz类加载流程(BizClassLoader)
- Biz类加载流程参考
BizClassLoader
- Plugin类加载流程参考
PluginClassLoader
- Plugin类加载流程参考
1 | public class BizClassLoader extends AbstractClasspathClassLoader { |
sofa-ark-maven-plugin打包Biz插件
启动日志示例
- 设置
logging.level.io.sofastack.guides.master=INFO
记录日志
1 | 20:34:34.539 [main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework |