
2. 创建SpringApplication
- 推断应用类型(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中,由于使用了响应式编程模型,因此需要使用Mono和Flux等响应式类型,并通过chain.filter(exchange)方法将请求传递给过滤器链中的下一个过滤器。
3.准备环境(ConfigurableEnvironment)
- 环境配置来源(按优先级从高到低):
// 命令行参数(最高优先级)
java -jar app.jar --server.port=8080
// 系统环境变量
System.getenv("JAVA_HOME")
// application.properties/yml 配置文件
// application-{profile}.properties/yml 特定环境配置
- 具体加载过程:
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");
}
- 常见配置示例:
# 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. 命令行参数
2. SPRING_APPLICATION_JSON 环境变量
3. java:comp/env JNDI属性
4. System.getProperties() 系统属性
5. 操作系统环境变量
6. random.* 随机属性
7. application-{profile}.properties/yml
8. application.properties/yml
- 获取配置的方式:
@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");
- 配置刷新机制:
@RefreshScope // 支持配置热更新
@Component
public class ConfigComponent {
@Value("${dynamic.property}")
private String dynamicProperty;
}
关键点:
- 环境准备是为了统一管理各种配置源
- 提供了灵活的配置方式和优先级机制
- 支持profile进行环境切换
- 可以通过多种方式获取配置
- 支持配置热更新
- 配置值可以被覆盖,高优先级的配置会覆盖低优先级的配置
这个阶段就是在应用启动前,把所有的配置信息都准备好,为后续的Bean创建和依赖注入做准备。
4. 创建并刷新 ApplicationContext
- 创建 ApplicationContext:
// 根据应用类型创建对应的上下文
ConfigurableApplicationContext context;
if (webApplicationType == WebApplicationType.SERVLET) {
context = new AnnotationConfigServletWebServerApplicationContext();
} else if (webApplicationType == WebApplicationType.REACTIVE) {
context = new AnnotationConfigReactiveWebServerApplicationContext();
} else {
context = new AnnotationConfigApplicationContext();
}
- 加载配置类:
@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);
}
}
- 注册Bean的几种方式:
// 1. @Component注解
@Component
public class UserService {
}
// 2. @Bean注解
@Bean
public OrderService orderService() {
return new OrderService

最低0.47元/天 解锁文章
10万+

被折叠的 条评论
为什么被折叠?



