1、简介 本文介绍了一些限制 WebClient 并发请求数量的方式。
2、服务端 限制 WebClient 并发请求数量是为了避免服务器因大量并发请求而宕机。有些服务自身也提供了一些限制策略。
2.1、一个简单的 Controller 为了演示,先定义一个简单的 @RestController,它返回固定范围的随机数字:
@RestController @RequestMapping("/random") public class RandomController { @GetMapping Integer getRandom() { return new Random().nextInt(50); } } 接下来,我们将模拟一些耗时的操作,并限制并发请求的数量。
2.2、服务器限制并发请求数 修改服务,模拟一个更真实的场景。
首先,限制服务器可接受的并发请求数,并在达到限制时抛出异常。
其次,增加处理响应的延迟,模拟耗时的操作。
创建 Concurrency 用于限制并发数量:
public class Concurrency { public static final int MAX_CONCURRENT = 5; static final AtomicInteger CONCURRENT_REQUESTS = new AtomicInteger(); public static int protect(IntSupplier supplier) { try { if (CONCURRENT_REQUESTS.incrementAndGet() > MAX_CONCURRENT) { throw new UnsupportedOperationException("max concurrent requests reached"); } TimeUnit.
1、概览 Groovy 是一种功能强大的动态 JVM 语言,具有众多特性。在 Spring 中使用 Groovy 可以大大提高应用程序的灵活性和可读性。从 Spring 4 开始 支持基于 Groovy 的配置。
在本教程中,我们将了解 Groovy 与 Spring 结合使用的各种方法。首先介绍了如何使用 Spring 提供的多个选项来创建 Groovy Bean 定义。接下来,了解如何使用 Groovy 脚本加载 Application Context。最后,学习如何使用 XML 和 GroovyScriptEngine 类将 Groovy 作为脚本执行(无需编译)。
2、Maven 依赖 首先,在 pom.xml 中定义 Groovy 依赖:
<dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy</artifactId> <version>3.0.12</version> </dependency> 此外,还需要添加 GMavenPlus 插件来编译 Groovy 文件:
<build> <plugins> <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> <version>1.9.0</version> <executions> <execution> <goals> <goal>addSources</goal> <goal>addTestSources</goal> <goal>generateStubs</goal> <goal>compile</goal> <goal>generateTestStubs</goal> <goal>compileTests</goal> <goal>removeStubs</goal> <goal>removeTestStubs</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 3、Bean 定义 传统上,开发人员通过 XML 配置来声明 Bean。这种方式后来被通过 Java 注解以编程方式定义 Bean 所取代。另一种声明 Bean 的方式是通过 Groovy 脚本。
PID 是进程标识符(Process Identifier)的缩写。在操作系统中,每个运行的进程都被分配一个唯一的 PID,用于标识进程。PID 通常是一个整数值,可以用来跟踪和管理进程的状态、资源分配以及进程间的通信。
本文将会介绍几种获取 Spring Boot 应用 PID 的方法。
ApplicationPidFileWriter ApplicationPidFileWriter 是 Spring Boot 提供的一个 Listener,它可以在应用启动后把 PID 写入到指定的文件。
它需要在启动前,通过编程式配置到应用中,并且需要在配置文件中指定要写入 PID 的文件。
application.yaml 配置如下:
spring: pid: # 写入 PID 的文件,可以是相对路径或绝对路径 file: app.pid # 如果 PID 无法写入,是否抛出异常 fail-on-write-error: true 在启动前,配置 ApplicationPidFileWriter 监听器:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.ApplicationPidFileWriter; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication springApplication = new SpringApplicationBuilder() .listeners(new ApplicationPidFileWriter()) // PID 监听 .
安全套接字层(SSL)和传输层安全(TLS)是在分层或面向服务的架构中保护系统之间通信的关键组件。在这样的架构中,Spring Boot 应用程序通常接受传入的网络连接或创建传出连接,开发人员的任务是配置应用程序以在这样的安全环境中工作。
如果你曾经使用过 Java 的 Security 和 SSL API,你可能意识到这不是一项特别简单的任务。你可能会在网上复制各种代码片段。有几个因素使得与 SSL 工作变得痛苦。
首先,你可能会收到用于生产环境的 SSL 资源文件,如证书和私钥。你可能需要为预生产测试生成不同的证书(通常使用自签名证书颁发机构)。这些证书通常以 Java Keystore 文件的形式存在,可以是 JKS 或 PKCS #12 格式,或者它们可能是 PEM 编码的文本文件。每种文件类型都需要不同的处理方式。
一旦你有了证书,你需要将其转换为可以传递给 Java Connection API 的形式。麻烦点就在这里,因为 Connection API 可以以多种方式进行配置:
有的要你提供 java.security.KeyStore(Keystore 和 Truststore) 实例。 有的要你提供 javax.net.ssl.KeyManager 和 javax.net.ssl.TrustManager 实例。 有的要你提供 javax.net.ssl.SSLContext 实例。 SSL 也是相当底层的,因此通常需要逐层解除抽象,以使用 java.security 或 java.net.ssl 包中的对象进行配置。例如,如果你想在 Spring RestTemplate 上配置SSL,你需要深入到支持它的 ClientHttpRequestFactory。对于典型的 Spring Boot 应用程序,可能是一个 HttpComponentsClientHttpRequestFactory、OkHttp3ClientHttpRequestFactory 或 SimpleClientHttpRequestFactory。每个 Factory 都提供了不同的配置API。
Spring Boot 配置 SSL 或 TLS 并不是什么新鲜事,但团队决定全面审视当前对 SSL 的支持,寻找改进和扩展支持的机会。我们希望 Spring Boot 3.
1、概览 使用 Spring Security,可以为应用配置身份认证和授权,以控制方法(如端点)的访问权限。
在 5.6 之前,使用 @EnableGlobalMethodSecurity 注解是标准的做法,在 5.6 之后,@EnableMethodSecurity 引入了一种更灵活的方法来配置方法安全授权(Method Security)。
在本教程中,我们将通过示例代码了解 @EnableMethodSecurity 如何代替 @EnableGlobalMethodSecurity,以及他们之间的区别。
2、@EnableMethodSecurity 和 @EnableGlobalMethodSecurity 让我们来看看方法授权如何与 @EnableMethodSecurity 和 @EnableGlobalMethodSecurity 配合使用。
2.1、@EnableMethodSecurity 通过 @EnableMethodSecurity,可以看到 Spring Security 为授权类型(Authorization Type)采用基于 Bean 的配置。
我们现在为每种类型都设置了一个配置,而不是全局配置。例如,Jsr250MethodSecurityConfiguration:
@Configuration(proxyBeanMethods = false) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) class Jsr250MethodSecurityConfiguration { // ... @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) Advisor jsr250AuthorizationMethodInterceptor() { return AuthorizationManagerBeforeMethodInterceptor.jsr250(this.jsr250AuthorizationManager); } @Autowired(required = false) void setGrantedAuthorityDefaults(GrantedAuthorityDefaults grantedAuthorityDefaults) { this.jsr250AuthorizationManager.setRolePrefix(grantedAuthorityDefaults.getRolePrefix()); } } MethodInterceptor 主要包含一个 AuthorizationManager,它现在将 “检查和返回最终决策的 AuthorizationDecision 对象” 的责任委托给适当的实现,这里是 AuthenticatedAuthorizationManager。
1、概览 在 Spring Boot 运行时,出于一些维护目的,我们可能需要动态地启用、禁用某些端点。
在本教程中,我们将学习如何使用 Spring Cloud、Spring Actuator 和 Apache 的 Commons Configuration 等几个常用库在运行时启用和禁用 Spring Boot 端点。
2、项目设置 以下是 Spring Boot 项目的关键设置。
2.1、Maven 依赖 首先,在 pom.xml 文件中添加 spring-boot-starter-actuator 依赖,用于暴露 /refresh 端点:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>2.7.5</version> </dependency> 接下来,添加 spring-cloud-starter 依赖,因为稍后需要使用其 @RefreshScope 注解来重载 Environment 中的属性源:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> <version>3.1.5</version> </dependency> 还必须在项目 pom.xml 文件的 <dependencyManagement> 中添加 Spring Cloud 的 BOM,以便 Maven 使用兼容版本的 spring-cloud-starter:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2021.0.5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 最后,由于我们需要在运行时重新加载文件的功能,所以还要添加 commons-configuration 依赖:
GSON 是由谷歌开源的一款 Java JSON 库。特点是轻量,只有一个 JAR,无任何其他依赖。高性能,支持以流式进行序列化/反序列化。并且抽象了基本的 JsonElement、JsonObject、JsonArray、JsonPrimitive 和 JsonNull,可以在无自定义 Java 对象的情况下构建、解析 JSON 对象。
本文将会指导你如何在 Spring Boot 中使用 Gson 代替默认的 Jackson 作为 JSON 序列化/反序列化框架。
添加依赖 在 pom.xml 中添加依赖。 gson 的版本已经被 Spring Boot 管理,所以不需要声明版本号。
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> 由于 Spring Boot 默认使用 Jackson,所以很多 Spring Boot 的组件、框架默认也会选择用 Jackson 作为 JSON 库。如果你确认项目中,没有其他地方使用到了 Jackson,那么可以从依赖中排除它。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> </exclusion> </exclusions> </dependency> 并且,在 @SpringBootApplication 注解中,排除掉 Jackson 的自动装配。
@SpringBootApplication(exclude = { JacksonAutoConfiguration.class }) 配置属性 在 application.
1、概览 在本教程中,我们将学习如何给 RestTemplate 配置 SSL 证书来访问 HTTPS 加密的 REST 服务。
2、设置 要确保 REST 服务的安全,我们需要使用证书和由证书生成的 Keystore。
证书可以从 CA 获取,在本文的示例中,使用的是自签名证书。
我们将使用 Spring 的 RestTemplate 来访问 HTTPS REST 服务。
首先,让我们创建一个 Controller 类 WelcomeController 和一个 /welcome 端点(返回一个简单的字符串响应):
@RestController public class WelcomeController { @GetMapping(value = "/welcome") public String welcome() { return "Welcome To Secured REST Service"; } } 然后,在 src/main/resources 文件夹中添加我们的 keystore:
src/main/resources |-keystore |-baeldung.p12 接下来,在 application.properties 文件中添加与 Keystore 相关的属性:
server.port=8443 server.servlet.context-path=/ # keystore 的格式 server.
1、概览 在本教程中,我们将学习如何在 Spring Boot 中实现不区分大小写的枚举映射。
2、Spring 默认的枚举映射 在处理请求参数时,Spring 依靠几个内置 Converter 来处理字符串转换。
通常情况下,将枚举作为请求参数时,默认会使用 StringToEnumConverterFactory 将传递的字符串转换为枚举。
该 Converter 会调用 Enum.valueOf(Class, String),这意味着给定的字符串必须要完全匹配枚举中的常量实例。
例如,让我们来看看 Level 枚举:
public enum Level { LOW, MEDIUM, HIGH } 接下来,创建一个使用枚举作为参数的 Handler Method:
@RestController @RequestMapping("enummapping") public class EnumMappingController { @GetMapping("/get") public String getByLevel(@RequestParam(required = false) Level level){ return level.name(); } } 使用 CURL 向 http://localhost:8080/enummapping/get?level=MEDIUM 发送一个请求:
curl http://localhost:8080/enummapping/get?level=MEDIUM Handler Method 会返回 MEDIUM,即枚举实例 MEDIUM 的名称(name())。
现在,让我们传递 medium,看看会发生什么:
curl http://localhost:8080/enummapping/get?level=medium {"timestamp":"2022-11-18T18:41:11.440+00:00","status":400,"error":"Bad Request","path":"/enummapping/get"} 如你所见,返回了无效请求异常:
1、概览 Spring Cloud Config 是 Spring Cloud 全家桶的一个子项目。它通过集中式独立的服务来管理各个服务的配置。Spring Cloud Config 拥有自己的属性管理库,但也可以集成 Git、Consul 和 Eureka 等开源项目。
在本文中,我们将了解在 Spring Cloud Config 中覆盖远程属性值的不同方法,以及 Spring 从 2.4 版本开始强制实施的限制,以及 3.0 版本中的变化。在本教程中,我们使用 Spring Boot 2.7.2。
2、创建 Spring Config Server 使用 Spring Cloud Config 创建外部化的配置服务器。
2.1、创建配置文件 在 application.properties 文件中定义的配置与所有客户端应用共享。也可以为指定应用或指定 Profile 定义特定配置。
首先,创建一个配置文件,其中包含为客户端应用提供的属性。
客户端应用命名为 baeldung,在 /resources/config 文件夹中创建 baeldung.properties 文件。
2.2、添加属性 在 baeldung.properties 文件中添加一些属性,然后在客户端应用中使用这些属性:
hello=Hello Jane Doe! welcome=Welcome Jane Doe! 还要在 resources/config/application.properties 文件中添加一个共享属性,Spring 将在所有客户端中共享该属性:
shared-property=This property is shared accross all client applications 2.