一、高级特性
(一)Profile使用
1、Profile场景切换
我们在开发过程中,就会进行不断的测试,不会是完全开发好了再进行测试,所以我们肯定是有开发环境,测试环境以及发布环境。
(1)模拟环境
- 启动测试
默认的启动,加载了我们的默认使用的application.properteis.
(2)激活其他场景
如果这样修改
此时你激活dev的话,那就要写8006才可以访问了。
(3)发布时修改也可以
java -jar xxx.jar --spring.profiles.active=prod
2、Profile进行条件装配
(1)提前理解
- 首先看我们这种情况
上面没什么问题吧,
(2)解决问题
如果现在我们的person在公司分了两类,一类是干活的员工,另外是管理的经历与老板。
- 那我们此时就可以用profile进行区别对待
- 启动测试
发现没有提供toString方法,进去添加
如果我们激活test的话就会是Boss
3、使用Profile进行分组
(二)外部化配置
1、什么是外部化配置
- 通过Java属性文件、YAML文件、环境变量、命令行参数进行配置;(总体包括了如上的14种)
常用的是画红线的两种。 - 然后进行后续用value或configurationProperties进行获取。
2、配置文件加载的优先级
(1)优先级分析
在这么一个顺序中,优先级越来越高,但是我们不用死记硬背,要记住后面的配置会覆盖调上一步配置的。
(2)资源文件所放置位置
他们的优先级的话,会是越往下越高。
- (1)与(2)比较简单就不说了
- (3)只要把你项目打成jar包与然后我们的application.yaml写在同一个目录,就可以了
- (4)就是在自己项目的jar包里面新建一个config文件进行配置。{他们是同一个目录}
(3)加载顺序
这个也是,下面加载的会覆盖上面加载的。
(4)小总结
指定环境优先,外部优先,后面配置的可以覆盖前面配置。
(三)自定义Starter
SpringBoot整合了很多东西,我们都可以引入相应的starter进行配置,然后使用他们的功能。但是有些时候会用到自定义的,现在在boot阶段不是很明显,在为服务器的时候就会很明显。
1、分析别人的starter
就看test的,test的我熟。
它们流弊就流在这里,整了AutoConfiguration的。
-
autoconfigure包中配置使用 META-INF/spring.factories 中 EnableAutoConfiguration 的值,使得项目启动加载指定的自动配置类
-
编写自动配置类 xxxAutoConfiguration -> xxxxProperties
- @Configuration
- @Conditional
- @EnableConfigurationProperties
- @Bean
- …
-
具体配置的步骤是
2、先创建一个空项目
- 然后再创建爱你一个模块
(1)模拟环境
- 项目结构
- 业务逻辑
(2)打包
相当于把它安装到本地库里面了。然后其他要使用的话就可以引入即可
(3)引入自己开发的包
3、其他项目引入看看
-
引入依赖
-
分析之前的情况
之前说到,在这里只有它这里写死的才会被默认加载,而我们自定义的还要经过出来才能被自动配置。 -
原先项目
然后重新打包clean与install。 -
在这里进行引入
二、SpringApplication创建初始化流程
1、SpringBoot启动过程
SpringBoot还是去调用的springApplication,具体原理是什么呢,又为我们准备了些什么呢
- 打断点看过程
可以分为两大步:创建SpringApplication与执行run方法
(1)创建SpringApplication的过程
-
加载资源(保存信息)
会加载判断保存一些信息。
-
判断当前主配置类(它会找你表示了SpringBootApplication注解的类)
-
看当前web应用的类型
会用WebApplicationType判断你web应用类型
最后我们这个项目肯定是返回了一个servlet类型的应用。 -
初始化启动器
getSpringFactoriesInstances进入这个方法发现我们的项目并没有什么初始化引导器。 -
找初始化:(它会去配置Spring.factories文件里面找)
发现有七个,如下的初始化器有两个,然后其他包里面肯定有配了5个。
-
找一些监听器
找到了九个 -
确定哪个是主类(会找哪个类有main方法)
-
小总结:在创建的SpringApplication的过程中,它会先找到相应的组件,然后保存起来。后续会使用这些组件。
(2)SpringBoot完整启动流程(执行run方法)
-
记录启动时间
-
创建引导上下文
获取到之前所有的BootStrappers挨个执行initialize()方法引导启动器上下文环境设置。 -
让当前应用进入handlers模式:java.awt.handlers(相当于自力更生模式了)
-
获取所有RunListener(运行时监听器)
getSpringFactoriesInstances还是这个方法去获取运行时监听器。
遍历所有的监听器,并且启动这些监听器,相当于一个时间通知机制,通知所有感兴趣系统正在启动过程的人,项目正在启动。【比如,你项目再获取的时候,你想获取一些信息,此时你就可以写一些监听器了,然后它在这一步就会通知你】 -
保存两面行参数(可能你有一个日志文件,后续要用)
-
准备环境的内容
有就直接返回,没有就会创建。【我们是servlet就会创建一个servlet环境,,环境信息会保存servlet的基本信息】
后续的就是进行配置
上面一步会读取所有配置源的配置属性值。然后接下来配置了profile的配置(就是我们用的那个注解,它会在这里获取)
-
绑定工作
-
监听器调用environmentPrepared这个方法
通知所有的监听器,准备工作已经完成 -
然后就是进行绑定了
然后返回
-
打印banner【这一步放行的话就会打印了】
-
创建IOC容器【非常重要】
根据当前项目类型创建相应容器。
-
记录启动的事件
-
准备容器信息{前面是准备基础环境信息}
-
应用初始化器
获取初始化器
遍历所有的初始化器,调用初始化器,来对IOC容器进行初始化的扩展。
-
遍历所有的监听器
通知所有的监听器
-
到这个方法的结束又去调用了contextloaded方法,通知所有的监听器,准备完成了。
-
-
刷新IOC容器
核心就是注册单实例组件哦(会实例化所有的组件了) -
然后又调用了所有监听器,通知监听器
-
调用所有的Runners
并且根据Order进行排序
遍历所有的runner并且调用run方法。
-
如果有异常就报错【原来如此,写了那么多demo,都是报这个错】
-
然后后续有调用了Running方法。
-
然后最后返回容器。就结束了。
2、SpringBoot自监听器
上面我们发现不管完成了多少,完成了什么,什么时候做了什么,都会通知所有的监听者,如果我们要进行监听的时候,我们就可以自己写监听器。
(1)先定义我们几个重要的类
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
public class MyApplicationContextInitializer implements ApplicationContextInitializer {
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("MyApplicationContextInitializer 初始化啦");
}
}
public class MyApplicationListener implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("MyApplicationListener 通知啦");
}
}
@Component
public class MyApplicationRunner implements ApplicationRunner {
public void run(ApplicationArguments args) throws Exception {
System.out.println("MyApplicationRunner 运行啦");
}
}
@Component
public class MyCommandLineRunner implements CommandLineRunner {
public void run(String... args) throws Exception {
System.out.println("执行了 MyCommandLineRunner");
}
}
public class MySpringApplicationRunListener implements SpringApplicationRunListener {
public void starting(ConfigurableBootstrapContext bootstrapContext) {
System.out.println("MySpringApplicationRunListener 启动啦");
}
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
System.out.println("MySpringApplicationRunListener 环境准备完成");
}
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("MySpringApplicationRunListener IOC容器准备完成");
}
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("MySpringApplicationRunListener IOC容器加载完成");
}
public void failed(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("MySpringApplicationRunListener 启动啦");
}
}
(2)这样整合
另外两个只要使用component注入即可。
- 启动测试
没有构造器
三、后续安排
后续的就是整合具体的应用了,比如后续的MQ啊,docker等,后续就慢慢的加油了,完结,撒花。