来自艾编程coding老师讲义,很散,很碎,有一定 SpringBoot 基础看会比较好。
1.SpringBoot 启动过程
还可以参考:Tomcat在SpringBoot中是如何启动的
启动类示例:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//程序的主入口
@SpringBootApplication //Springboot应用
public class DemoApplication {
public static void main(String[] args) {
//开启了一个服务!
SpringApplication.run(DemoApplication.class, args);
}
}
applicationContext.xml < == > @Configuration
bean < == > @Bean
import < == > @Import
1.1 启动流程图
1.2 自动装配过程核心调用链
@SpringBootApplication
--> @EnableAutoConfiguration
--> @AutoConfigurationImportSelector --> #selectImports --> #getAutoConfigurationEntry --> #getCandidateConfigurations
--> SpringFactoriesLoader --> #loadFactoryNames --> #loadSpringFactories --> #FACTORIES_RESOURCE_LOCATION (META-INF/spring.factories)
--> @AutoConfigurationPackage --> AutoConfigurationPackages.Registrar
其中AutoConfigurationImportSelector#getCandidateConfigurations
方法很关键,会去读取META-INF/spring.factories
。
源码如下:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
1.3 SpringApplication.run()
大致流程
- 1.推断我们的应用是web应用还是 普通应用!
- 2.加载初始化!
- 3.设置监听器
- 4.推断main方法,找到运行的主类
核心部分源码如下:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
1.4 YAML 配置文件
Yet Another Markup Language
强调这种语言以数据做为中心,而不是以标记语言为重点。
语法要点:冒号后空一格、下一层级可用两个空格作为缩进表示、同级别配置左侧需要对齐。。
简单示例:
字面量键值对:
k: value
对象,map
# 这句是注释
student:
name: coding
age: 3
student: {name: coding, age: 3}
数组(List,Set)
#语法
pets:
- cat
- dog
- pig
pets: [cat,dog,pig]
1.5 @ConfigurationProperties
@ConfigurationProperties
和 YAML 配置是黄金搭档。
SpringBoot自动配置底层基本全部都使用了这个注解。
@ConfigurationProperties
VS @Value
特性对比 | @ConfigurationProperties | @Value |
---|---|---|
功能 | 批量从配置文件中注入属性 | 一个个指定 |
松散绑定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持! |
在配置类中,通过注解@EnableConfigurationProperties
即可自动装配@ConfigurationProperties
注解标记的配置类。
可参考:DemoServiceProperties.java、DemoServiceAutoConfiguration.java
2.十五次架构演进
2.1 单体架构
问题:用户量增大。
2.2 tomcat 和数据库分离
问题:用户暴增,并发读写,瓶颈!
2.3 引入分布式缓存本地缓存
问题:缓存一致性问题,缓存穿透、缓存雪崩.... 热点数据集中失效等。
2.4 负载均衡
问题:单点登陆,session共享,文件上传下载!
2.5 数据库读写分离
问题: 数据库同步,数据一致性问题!
2.6 数据库按照业务分库
2.7 把大表拆分为一个个小表
问题:大规模并发!
2.8 LVS,F5,多个nginx实现负载均衡
2.9 通过DNS 实现机房的负载均衡
机房级的水平扩展
2.10 引用NoSQL数据库,搜索引擎
2.11 大应用拆分为小应用
2.12 将公共模板抽象为微服务化
2.13 引入服务总线
2.14容器化
Docker + k8s。
2.15 云平台系统
Iaas: 基础设施即服务
Paas:平台即服务
Sass: 软件即服务
评论区