Springboot 的启动流程【超级详细 | 附带思维导图】

在这里插入图片描述

2. 创建SpringApplication

  1. 推断应用类型(WebApplicationType)
// SpringBoot会检查classpath中的类来判断应用类型
if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", null)) {
   
   
    return WebApplicationType.REACTIVE;  // 响应式Web应用
} else if (ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", null)) {
   
   
    return WebApplicationType.SERVLET;   // 传统Web应用
} else {
   
   
    return WebApplicationType.NONE;      // 普通应用
}

拓展

  • REACTIVE 响应式Web应用:

Spring Cloud Gateway中确实使用了响应式编程模型。Spring Cloud Gateway是基于Spring WebFlux构建的,它采用了响应式编程范式,利用了Project Reactor和Netty等技术。

Spring Cloud Gateway中,请求的处理是通过一系列的过滤器(Filter)来实现的。每个过滤器都可以对请求进行拦截、转换、路由等操作。这些过滤器组成了一个过滤器链(Filter Chain),请求会依次通过这些过滤器。

在编写自定义过滤器时,你可以通过chain.filter(exchange)方法将请求传递给过滤器链中的下一个过滤器,这个方法返回一个Mono<Void>对象,表示异步地处理请求。

下面是一个自定义过滤器的示例:

@Component
public class CustomFilter implements GlobalFilter {
   
   
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
   
   
        // 在此处进行请求的预处理
        ServerHttpRequest request = exchange.getRequest().mutate()
                .header("Custom-Header", "Value")
                .build();
        
        return chain.filter(exchange.mutate().request(request).build())
                .then(Mono.fromRunnable(() -> {
   
   
                    // 在此处进行响应的后处理
                }));
    }
}

在这个示例中,filter方法接收一个ServerWebExchange对象和一个GatewayFilterChain对象。通过chain.filter(exchange)将请求传递给下一个过滤器,并在请求处理完成后进行响应的后处理。

总之,在Spring Cloud Gateway中,由于使用了响应式编程模型,因此需要使用MonoFlux等响应式类型,并通过chain.filter(exchange)方法将请求传递给过滤器链中的下一个过滤器。

3.准备环境(ConfigurableEnvironment)

  1. 环境配置来源(按优先级从高到低):
// 命令行参数(最高优先级)
java -jar app.jar --server.port=8080

// 系统环境变量
System.getenv("JAVA_HOME")

// application.properties/yml 配置文件
// application-{profile}.properties/yml 特定环境配置
  1. 具体加载过程:
public class EnvironmentPrepareExample {
   
   
    
    // 创建环境对象
    ConfigurableEnvironment environment = new StandardEnvironment();
    
    // 添加属性源
    environment.getPropertySources().addLast(
        new ResourcePropertySource("application.properties")
    );
    
    // 设置激活的配置文件
    environment.setActiveProfiles("dev", "local");
    
    // 获取配置值
    String serverPort = environment.getProperty("server.port");
    String dbUrl = environment.getProperty("spring.datasource.url");
}
  1. 常见配置示例:
# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456
  
server:
  port: 8080
  
logging:
  level:
    root: INFO

# 自定义配置
custom:
  property: value
  1. 配置优先级(从高到低):
1. 命令行参数
2. SPRING_APPLICATION_JSON 环境变量
3. java:comp/env JNDI属性
4. System.getProperties() 系统属性
5. 操作系统环境变量
6. random.* 随机属性
7. application-{profile}.properties/yml
8. application.properties/yml
  1. 获取配置的方式:
@Value("${server.port}")
private String serverPort;

@ConfigurationProperties(prefix = "custom")
public class CustomProperties {
   
   
    private String property;
    // getter/setter
}

@Autowired
private Environment environment;
String value = environment.getProperty("custom.property");
  1. 配置刷新机制:
@RefreshScope  // 支持配置热更新
@Component
public class ConfigComponent {
   
   
    @Value("${dynamic.property}")
    private String dynamicProperty;
}

关键点:

  • 环境准备是为了统一管理各种配置源
  • 提供了灵活的配置方式和优先级机制
  • 支持profile进行环境切换
  • 可以通过多种方式获取配置
  • 支持配置热更新
  • 配置值可以被覆盖,高优先级的配置会覆盖低优先级的配置

这个阶段就是在应用启动前,把所有的配置信息都准备好,为后续的Bean创建和依赖注入做准备。

4. 创建并刷新 ApplicationContext

  1. 创建 ApplicationContext:
// 根据应用类型创建对应的上下文
ConfigurableApplicationContext context;
if (webApplicationType == WebApplicationType.SERVLET) {
   
   
    context = new AnnotationConfigServletWebServerApplicationContext();
} else if (webApplicationType == WebApplicationType.REACTIVE) {
   
   
    context = new AnnotationConfigReactiveWebServerApplicationContext();
} else {
   
   
    context = new AnnotationConfigApplicationContext();
}
  1. 加载配置类:
@Configuration  // 配置类
public class AppConfig {
   
   
    
    @Bean  // 定义Bean
    public UserService userService() {
   
   
        return new UserService();
    }
    
    @Bean
    public OrderService orderService() {
   
   
        return new OrderService(userService());  // 依赖注入
    }
}

// 启动类中的自动配置
@SpringBootApplication
public class Application {
   
   
    public static void main(String[] args) {
   
   
        SpringApplication.run(Application.class, args);
    }
}
  1. 注册Bean的几种方式:
// 1. @Component注解
@Component
public class UserService {
   
   
}

// 2. @Bean注解
@Bean
public OrderService orderService() {
   
   
    return new OrderService
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值