如何在服务发现库中禁用 CompositeDiscoveryClient 和 SimpleDiscoveryClient
How to disable CompositeDiscoveryClient and SimpleDiscoveryClient in service discovery library
我们基于 spring-cloud-commons SPI 编写了一个内部服务发现 (SD) 客户端,这意味着它提供了接口 ServiceRegistry
和 DiscoveryClient
以及其他一些 Spring-提供抽象。
使用我们库的应用程序只需将它添加到它们的 pom 文件中,它就会使用自己的实现自动装配 DiscoveryClient
,InHouseDiscoveryClient
<dependency>
<groupId>blah.blah<groupId>
<artifactId>inhouse-service-discovery-client<artifactId>
<dependency>
但是,最好不要在代码中引用 InHouseDiscoveryClient
,而是使用界面 DiscoveryClient
,如下所示
# Good
@Autowired
DiscoveryClient client;
# Bad (binds app to a particular SD implementation)
@Autowired
InHouseDiscoveryClient client;
因此,我们需要将 spring-cloud-commons
添加到项目中。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
问题由此开始。公共库实际上自动装配了 DiscoveryClient
的两个额外实现 - SimpleDiscoveryClient
和 CompositeDiscoveryClient
。
这给我们的客户带来了奇怪的用户体验。用户发现自己拥有这些额外的 bean,而不是简单地拥有 InHouseDiscoveryClient
。
是否可以防止 spring-cloud-commons
的 DiscoveryClient
实现自动装配?如果是这样,是否可以在我们的库中而不是在最终用户的应用程序中完成?
我最终在我的库中扩展了 AutoConfigurationImportFilter
,以从云共享中删除自动装配的 bean。我还删除了它的健康指示器,但我们有一个非常特殊的理由这样做 - 很可能宁愿保留它。
my.package
public class StratusDiscoveryExclusionFilter implements AutoConfigurationImportFilter {
private static final Set<String> SHOULD_SKIP = new HashSet<>(
Arrays.asList(
// DiscoveryClient Beans
"org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration",
"org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration",
// Health indicators
"org.springframework.cloud.client.CommonsClientAutoConfiguration")
);
/**
* For each class name, provide an assocated boolean array indicated whether or not to include
*/
@Override
public boolean[] match(String[] classNames, AutoConfigurationMetadata metadata) {
boolean[] matches = new boolean[classNames.length];
for (int i = 0; i < classNames.length; i++) {
matches[i] = !SHOULD_SKIP.contains(classNames[i]);
}
return matches;
}
}
我想在我图书馆的 spring.factories
文件中添加对此的引用
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=my.package.MyExclusionFilter
我们基于 spring-cloud-commons SPI 编写了一个内部服务发现 (SD) 客户端,这意味着它提供了接口 ServiceRegistry
和 DiscoveryClient
以及其他一些 Spring-提供抽象。
使用我们库的应用程序只需将它添加到它们的 pom 文件中,它就会使用自己的实现自动装配 DiscoveryClient
,InHouseDiscoveryClient
<dependency>
<groupId>blah.blah<groupId>
<artifactId>inhouse-service-discovery-client<artifactId>
<dependency>
但是,最好不要在代码中引用 InHouseDiscoveryClient
,而是使用界面 DiscoveryClient
,如下所示
# Good
@Autowired
DiscoveryClient client;
# Bad (binds app to a particular SD implementation)
@Autowired
InHouseDiscoveryClient client;
因此,我们需要将 spring-cloud-commons
添加到项目中。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
问题由此开始。公共库实际上自动装配了 DiscoveryClient
的两个额外实现 - SimpleDiscoveryClient
和 CompositeDiscoveryClient
。
这给我们的客户带来了奇怪的用户体验。用户发现自己拥有这些额外的 bean,而不是简单地拥有 InHouseDiscoveryClient
。
是否可以防止 spring-cloud-commons
的 DiscoveryClient
实现自动装配?如果是这样,是否可以在我们的库中而不是在最终用户的应用程序中完成?
我最终在我的库中扩展了 AutoConfigurationImportFilter
,以从云共享中删除自动装配的 bean。我还删除了它的健康指示器,但我们有一个非常特殊的理由这样做 - 很可能宁愿保留它。
my.package
public class StratusDiscoveryExclusionFilter implements AutoConfigurationImportFilter {
private static final Set<String> SHOULD_SKIP = new HashSet<>(
Arrays.asList(
// DiscoveryClient Beans
"org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration",
"org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration",
// Health indicators
"org.springframework.cloud.client.CommonsClientAutoConfiguration")
);
/**
* For each class name, provide an assocated boolean array indicated whether or not to include
*/
@Override
public boolean[] match(String[] classNames, AutoConfigurationMetadata metadata) {
boolean[] matches = new boolean[classNames.length];
for (int i = 0; i < classNames.length; i++) {
matches[i] = !SHOULD_SKIP.contains(classNames[i]);
}
return matches;
}
}
我想在我图书馆的 spring.factories
文件中添加对此的引用
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=my.package.MyExclusionFilter