我们正在整个公司定义微服务基础设施。我们创建了自己的父母",它定义了我们服务的BOM。此外,我们有几个" starter"我们的服务可以使用的项目和小型库。 (例如,服务可以包括" starter-stream"包含Kafka的依赖项。)
流式实用程序库为Kafka设置提供了自己的自动配置,并要求禁用Kafka的默认自动配置。这很简单,我们可以要求任何使用该库的微服务添加"排除"。
我正在寻找的是一种以编程方式执行此操作的方法,这样我们就不必在EACH Web服务中添加排除。
我知道这可能是一种独特的情况,我考虑这样做的一种可能方式是在我们的实用程序库中添加一个EnvironmentPostProcessor,它将排除添加到spring.autoconfigure.exclude
。如果属性已经存在,我们可以使其足够聪明以连接排除。
有没有更优雅的方式来做这种事情?
答案 0 :(得分:2)
我认为您的建议可以通过EnvironmentPostProcessor
修改spring.auconfigure.exclude
。
另一种时髦的方法可能是org.springframework.boot.autoconfigure.AutoConfigurationImportSelector
的子类化并覆盖org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getExclusions
,以便它将已配置的排除项与您添加的排除项组合在一起。
public class MyCustomSelector extends AutoConfigurationImportSelector {
@Override
protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
Set<String> exclusions = super.getExclusions(metadata, attributes);
exclusions.add("some.other.config.Configuration");
return exclusions;
}
}
然后您可以将其与@Import(MyCustomSelector.class)
一起使用。
答案 1 :(得分:0)
我们最终找到的解决方案是:
此类将创建条目或将其链接到spring.autoconfigure.exclude
public class AutoConfigurationExclusion implements EnvironmentPostProcessor{
private static final String SPRING_EXCLUDE_PROPERTY = "spring.autoconfigure.exclude";
String exclusionList;
public AutoConfigurationExclusion(Class<?> ... classes) {
StringBuilder builder = new StringBuilder();
for (Class<?> clazz : classes) {
if (builder.length() > 0) {
builder.append(",");
}
builder.append(clazz.getCanonicalName());
}
exclusionList = builder.toString();
}
public AutoConfigurationExclusion(String ... classes) {
StringBuilder builder = new StringBuilder();
for (String className : classes) {
if (builder.length() > 0) {
builder.append(",");
}
builder.append(className);
}
exclusionList = builder.toString();
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String excludes = environment.getProperty(SPRING_EXCLUDE_PROPERTY);
if (StringUtils.isBlank(excludes)) {
excludes = exclusionList;
} else {
excludes = excludes + "," + exclusionList;
}
Map<String, Object> map = new HashMap<>();
map.put(SPRING_EXCLUDE_PROPERTY, excludes);
SpringPropertyOverrideHelper.overrideValues(environment.getPropertySources(), map);
}
}
还有用于获取/创建新属性源以保存“覆盖”值的静态助手,并且该源被添加为第一个属性源。
public class SpringPropertyOverrideHelper {
private static final String PROPERTY_SOURCE_NAME = "overrideProperties";
public static void overrideValues(MutablePropertySources propertySources, Map<String, Object> propertyMap) {
MapPropertySource target = null;
if (propertySources.contains(PROPERTY_SOURCE_NAME)) {
PropertySource<?> source = propertySources.get(PROPERTY_SOURCE_NAME);
if (source instanceof MapPropertySource) {
target = (MapPropertySource) source;
for (Map.Entry<String, Object> entry : propertyMap.entrySet()) {
target.getSource().put(entry.getKey(), entry.getValue());
}
}
} else {
target = new MapPropertySource(PROPERTY_SOURCE_NAME, propertyMap);
}
if (!propertySources.contains(PROPERTY_SOURCE_NAME)) {
propertySources.addFirst(target);
}
}
private SpringPropertyOverrideHelper() {
}
}