Spring Boot - 以编程方式禁用自动配置

时间:2017-08-16 16:47:31

标签: spring-boot

我们正在整个公司定义微服务基础设施。我们创建了自己的父母",它定义了我们服务的BOM。此外,我们有几个" starter"我们的服务可以使用的项目和小型库。 (例如,服务可以包括" starter-stream"包含Kafka的依赖项。)

流式实用程序库为Kafka设置提供了自己的自动配置,并要求禁用Kafka的默认自动配置。这很简单,我们可以要求任何使用该库的微服务添加"排除"。

我正在寻找的是一种以编程方式执行此操作的方法,这样我们就不必在EACH Web服务中添加排除。

我知道这可能是一种独特的情况,我考虑这样做的一种可能方式是在我们的实用程序库中添加一个EnvironmentPostProcessor,它将排除添加到spring.autoconfigure.exclude。如果属性已经存在,我们可以使其足够聪明以连接排除。

有没有更优雅的方式来做这种事情?

2 个答案:

答案 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() {
    }

}