09、原理解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 09、原理解析

09、原理解析

1、Profile功能

为了方便多环境适配,springboot简化了profile功能。

1、application-profile功能

默认配置文件 application.yaml;任何时候都会加载


指定环境配置文件 application-{env}.yaml


激活指定环境


配置文件激活

命令行激活:java -jar xxx.jar –spring.profiles.active=prod --person.name=haha

修改配置文件的任意值,命令行优先

默认配置与环境配置同时生效


同名配置项,profile配置优先


测试代码

@RestController
public class HelloController {
    @Value("${person.name}")
    private String name;
    @GetMapping("/")
    public String hello(){
        return "Hello "+name;
    }
}
#################################################application.properties###############
spring.profiles.active=prod
server.port=8080
##############################################application-prod.yaml##################
person:
  name: prod-李四
server:
  port: 8000
##############################################application-test.yaml##################  
person:
  name: test-张三
server:
  port: 7000  

2、@Profile条件装配功能

@Configuration
public class MyConfig {
    @Profile("prod")  //当时生产环境的时候加载该组件
    @Bean
    public Color red(){
        return new Color();
    }
    @Profile("test")//当时测试环境的时候加载该组件
    @Bean
    public Color green(){
        return new Color();
    }
}

3、profile分组

测试代码

###########################################Person####################################
public interface Person {
    String getName();
    Integer getAge();
}
#######################################Boss########################################
@Profile("test") //该类在测试的条件下才会生效. 进行数据绑定->被加载进Spring容器.
@Component
@ConfigurationProperties("person") //将该类与配置文件的person对应的属性进行绑定.
@Data
public class Boss implements Person{
    private String name;
    private Integer age;
}
##########################################Worker##################################
@Profile("prod") //该类在生产的条件下才会生效. 进行数据绑定->被加载进Spring容器.
@Component
@ConfigurationProperties("person") //将该类与配置文件的person对应的属性进行绑定.
@Data
public class Worker implements Person{
    private String name;
    private Integer age;
}
################################################HelloController######################
@RestController
public class HelloController {
    @Autowired
    private Person person;
    @GetMapping("/")
    public String hello(){
        return person.getClass().toString();
    }
    @GetMapping("/person")
    public Person person(){
        return person;
    }
}    
###################application.properties###################################3
spring.profiles.active=myprod
server.port=8080
# 分组
spring.profiles.group.myprod[0]=ppd
spring.profiles.group.myprod[1]=prod
spring.profiles.group.mytest[0]=test
###################application-ppd.yaml##########################################
###################application-prod.yaml###########################################
###################application-test.yaml############################################

2、外部化配置

https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config


Default properties (specified by setting SpringApplication.setDefaultProperties).


@PropertySource annotations on your @Configuration classes. Please note that such property sources are not added to the Environment until the application context is being refreshed. This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.


Config data (such as **application.properties** files)


A RandomValuePropertySource that has properties only in random.*.


OS environment variables.


Java System properties (System.getProperties()).


JNDI attributes from java:comp/env.


ServletContext init parameters.


ServletConfig init parameters.


Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).


Command line arguments.


properties attribute on your tests. Available on @SpringBootTest and the test annotations for testing a particular slice of your application.


@TestPropertySource annotations on your tests.


Devtools global settings properties in the $HOME/.config/spring-boot directory when devtools is active.


1、外部配置源

常用:Java属性文件YAML文件环境变量命令行参数

2、配置文件查找位置


(1) classpath 根路径

(2) classpath 根路径下config目录

(3) jar包当前目录

(4) jar包当前目录的config目录

(5) /config子目录的直接子目录

优先级从低到高…后者会覆盖前者…

79b06b6bc0694fa68f0d23082258d055.png


3、配置文件加载顺序:


当前jar包内部的application.properties和application.yml


当前jar包内部的application-{profile}.properties 和 application-{profile}.yml


引用的外部jar包的application.properties和application.yml


引用的外部jar包的application-{profile}.properties 和 application-{profile}.yml


4、指定环境优先,外部优先,后面的可以覆盖前面的同名配置项

3、自定义starter

1、starter启动原理

  • starter-pom引入 autoconfigurer 包


b9982256465d1bbe84e62dea24ecd73c.png

autoconfigure包中配置使用 META-INF/spring.factories 中 EnableAutoConfiguration 的值,使得项目启动加载指定的自动配置类


编写自动配置类 xxxAutoConfiguration -> xxxxProperties


@Configuration

@Conditional

@EnableConfigurationProperties

@Bean

引入starter — xxxAutoConfiguration — 容器中放入组件 ---- 绑定xxxProperties ---- 配置项


2、自定义starter

atguigu-hello-spring-boot-starter(启动器)

atguigu-hello-spring-boot-starter-autoconfigure(自动配置包)


后序再搞…

4、SpringBoot原理

Spring原理【Spring注解】、SpringMVC原理、自动配置原理、SpringBoot原理

1、SpringBoot启动过程

创建 SpringApplication


保存一些信息。

判定当前应用的类型。ClassUtils。Servlet

bootstrappers**:初始启动引导器(List):去spring.factories文件中找** org.springframework.boot.Bootstrapper

找 ApplicationContextInitializer;去spring.factories****找 ApplicationContextInitializer

List<ApplicationContextInitializer<?>> initializers

找 ApplicationListener ;应用监听器。去spring.factories****找 ApplicationListener

List<ApplicationListener<?>> listeners

运行 SpringApplication


StopWatch

记录应用的启动时间

**创建引导上下文(Context环境)**createBootstrapContext()

获取到所有之前的 bootstrappers 挨个执行 intitialize() 来完成对引导启动器上下文环境设置

让当前应用进入headless模式。java.awt.headless

获取所有 RunListener**(运行监听器)【为了方便所有Listener进行事件感知】**

getSpringFactoriesInstances 去spring.factories****找 SpringApplicationRunListener.

遍历 SpringApplicationRunListener 调用 starting 方法;

相当于通知所有感兴趣系统正在启动过程的人,项目正在 starting。

保存命令行参数;ApplicationArguments

准备环境 prepareEnvironment();

返回或者创建基础环境信息对象。StandardServletEnvironment

配置环境信息对象。

读取所有的配置源的配置属性值。

绑定环境信息

监听器调用 listener.environmentPrepared();通知所有的监听器当前环境准备完成

创建IOC容器(createApplicationContext())

根据项目类型(Servlet)创建容器,

当前会创建 AnnotationConfigServletWebServerApplicationContext

准备ApplicationContext IOC容器的基本信息 prepareContext()

保存环境信息

IOC容器的后置处理流程。

应用初始化器;applyInitializers;

遍历所有的 ApplicationContextInitializer 。调用 initialize.。来对ioc容器进行初始化扩展功能

遍历所有的 listener 调用 contextPrepared。EventPublishRunListenr;通知所有的监听器****contextPrepared

所有的监听器 调用 contextLoaded。通知所有的监听器 contextLoaded;

**刷新IOC容器。**refreshContext

创建容器中的所有组件(Spring注解)

容器刷新完成后工作?afterRefresh

所有监听 器 调用 listeners.started(context); 通知所有的监听器 started

**调用所有runners;**callRunners()

获取容器中的 ApplicationRunner

获取容器中的 CommandLineRunner

合并所有runner并且按照@Order进行排序

遍历所有的runner。调用 run 方法

如果以上有异常,

调用Listener 的 failed

调用所有监听器的 running 方法 listeners.running(context); 通知所有的监听器 running

**running如果有问题。继续通知 failed 。**调用所有 Listener 的 **failed;**通知所有的监听器 failed


public interface Bootstrapper {
  /**
   * Initialize the given {@link BootstrapRegistry} with any required registrations.
   * @param registry the registry to initialize
   */
  void intitialize(BootstrapRegistry registry);
}

76ec1d1e450c41e31469f311bf48aa9b.png

0ae95ce26b19b8cf270ee006cda2ad13.png

11f8ad6139ecaff8c26c709e6f02bced.png


@FunctionalInterface
public interface ApplicationRunner {
  /**
   * Callback used to run the bean.
   * @param args incoming application arguments
   * @throws Exception on error
   */
  void run(ApplicationArguments args) throws Exception;
}
@FunctionalInterface
public interface CommandLineRunner {
  /**
   * Callback used to run the bean.
   * @param args incoming main method arguments
   * @throws Exception on error
   */
  void run(String... args) throws Exception;
}

2、Application Events and Listeners

https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-application-events-and-listeners


ApplicationContextInitializer


ApplicationListener


SpringApplicationRunListener


3、ApplicationRunner 与 CommandLineRunner


相关文章
|
14天前
|
运维 持续交付 云计算
深入解析云计算中的微服务架构:原理、优势与实践
深入解析云计算中的微服务架构:原理、优势与实践
44 1
|
2月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
50 3
|
2月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
22天前
|
运维 持续交付 虚拟化
深入解析Docker容器化技术的核心原理
深入解析Docker容器化技术的核心原理
45 1
|
15天前
|
存储 供应链 算法
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景
40 0
|
1月前
|
算法 Java 数据库连接
Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性
本文详细介绍了Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性。连接池通过复用数据库连接,显著提升了应用的性能和稳定性。文章还展示了使用HikariCP连接池的示例代码,帮助读者更好地理解和应用这一技术。
48 1
|
18天前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
46 0
|
2月前
|
数据采集 存储 编解码
一份简明的 Base64 原理解析
Base64 编码器的原理,其实很简单,花一点点时间学会它,你就又消除了一个知识盲点。
80 3
|
24天前
|
API 持续交付 网络架构
深入解析微服务架构:原理、优势与实践
深入解析微服务架构:原理、优势与实践
22 0
|
25天前
|
存储 供应链 物联网
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景

推荐镜像

更多