如何使 ConfigurationProperties bean 中的验证注释和 @FeignClient 接口一起工作?
How to make both validation annotations in a ConfigurationProperties bean and a @FeignClient interface work together?
假设我有这个 application.yml(这将取决于环境,例如通过 Spring 配置文件):
app.remote:
url: http://whatever.url.it.is:8080/
和匹配 Java 风格的配置属性 class:
@Configuration
@ConfigurationProperties("app.remote")
public class MyRemoteProperties {
@NotBlank
private String url;
// matching getter/setter...
}
我想为我的遥控器安装某种客户端 url:
@Service
@FeignClient(value = "remote", url = "${app.remote.url}")
public interface MyRemote {
@GetMapping("/what/ever/rest/api")
String stuff();
}
很遗憾,我无法获得 MyRemoteProperties
的验证工作,例如当 app.remote.url
属性 为空白(空)时,应用程序无法启动(Spring 连接 MyRemote
bean 失败)并且出现此错误:
Caused by: java.lang.IllegalStateException: No Feign Client for
loadBalancing defined. Did you forget to include
spring-cloud-starter-netflix-ribbon?
(而且我不想要负载平衡;我假设这是因为 URL 在某些时候是空的,然后它需要一些负载平衡器配置,因此错误消息中的 Ribbon 在这里)。
或者我不知道如何将它插入到 MyRemote 接口的配置中,例如我也试过:
@FeignClient(value = "remote", configuration = MyRemoteProperties.class)
但结果相同。
如何让这个验证工作起作用?
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在调用接口的某个点:
@Service
public RandomServiceOrController {
@Autowired
private MyRemote myRemote;
public void processMyStuff() {
// ...
String myStuff = myRemote.stuff();
// ...
}
}
不要忘记 Java 属性上的 @Validated
注释 class:
@Validated
@Configuration
@ConfigurationProperties("app.remote")
public class MyRemoteProperties {
@NotBlank
private String url;
// matching getter/setter...
}
您的应用程序不会启动 因为 缺少 属性,而不是因为您不需要的未定义的负载平衡客户端(从而使它的错误信息更加尴尬)。
假设我有这个 application.yml(这将取决于环境,例如通过 Spring 配置文件):
app.remote:
url: http://whatever.url.it.is:8080/
和匹配 Java 风格的配置属性 class:
@Configuration
@ConfigurationProperties("app.remote")
public class MyRemoteProperties {
@NotBlank
private String url;
// matching getter/setter...
}
我想为我的遥控器安装某种客户端 url:
@Service
@FeignClient(value = "remote", url = "${app.remote.url}")
public interface MyRemote {
@GetMapping("/what/ever/rest/api")
String stuff();
}
很遗憾,我无法获得 MyRemoteProperties
的验证工作,例如当 app.remote.url
属性 为空白(空)时,应用程序无法启动(Spring 连接 MyRemote
bean 失败)并且出现此错误:
Caused by: java.lang.IllegalStateException: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?
(而且我不想要负载平衡;我假设这是因为 URL 在某些时候是空的,然后它需要一些负载平衡器配置,因此错误消息中的 Ribbon 在这里)。
或者我不知道如何将它插入到 MyRemote 接口的配置中,例如我也试过:
@FeignClient(value = "remote", configuration = MyRemoteProperties.class)
但结果相同。
如何让这个验证工作起作用?
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在调用接口的某个点:
@Service
public RandomServiceOrController {
@Autowired
private MyRemote myRemote;
public void processMyStuff() {
// ...
String myStuff = myRemote.stuff();
// ...
}
}
不要忘记 Java 属性上的 @Validated
注释 class:
@Validated
@Configuration
@ConfigurationProperties("app.remote")
public class MyRemoteProperties {
@NotBlank
private String url;
// matching getter/setter...
}
您的应用程序不会启动 因为 缺少 属性,而不是因为您不需要的未定义的负载平衡客户端(从而使它的错误信息更加尴尬)。