Spring Boot YAML配置-如何加载派生类类型

时间:2018-07-23 06:32:27

标签: java spring-boot inheritance interface yaml

是否可以加载基于yaml的某些接口的派生类?

因此,我正在构建此通用的http存根服务器进行测试。我想做的是通过一些匹配器匹配请求参数来识别存根接口。匹配器是一个接口。该配置包含一个匹配器列表,每个匹配器都有其类型和参数。

config:
  stubs:
    - 
      name: my-first-stub
      matcher: 
        type: ExactPathMatcher
        path: /stub/one
    -
      name: my-second-stub
      matcher: 
        type: StartsWithPathMatcher
        path: /stub/two
    -
      name: my-get-catch-all
      matcher: 
        type: MethodMatcher
        method: GET

当前,我使用MatcherConfig类加载该类,该类接收类型和所有匹配器类型(路径和方法)的所有可能参数。这很讨厌,因为两者都不是必需的。它具有一种根据类型和参数创建真正的Matcher的方法。

我想要的是直接从配置中加载正确的匹配器类。配置将如下所示:

config:
  stubs:
    - 
      name: my-first-stub
      exact-path-matcher: 
        path: /stub/one
    -
      name: my-second-stub
      starts-with-path-matcher: 
        path: /stub/two
    -
      name: my-get-catch-all
      method-matcher: 
        method: GET

并且StubConfig类现在不包含MatcherConfig的实例,而是接口Matcher的实例,上面带有特定的派生类。

使用YAML配置可以吗?还是其他?

课程:

@Component
@ConfigurationProperties("config") // prefix app, find app.* values
public class StubsConfig {

    @NestedConfigurationProperty
    private final List<StubConfig> stubs = new ArrayList<>();

    public List<StubConfig> getStubs() {
        return stubs;
    }
}

public class StubConfig {

    private String name;
    private StubMatcherConfig matcher;

    ...
}

public class StubMatcherConfig {

    private static final Logger logger = LoggerFactory.getLogger(StubMatcherConfig.class);

    private static final HashMap<StubMatcherType, Class<? extends StubMatcher>> matcherMap = new HashMap<>();
    static {
        matcherMap.put(StubMatcherType.ExactPathMatcher, ExactPathMatcher.class);
        matcherMap.put(StubMatcherType.StartsWithPathMatcher, StartsWithPathMatcher.class);
    }

    private StubMatcherType type;
    private String path;
    private HttpMethod method;

    public StubMatcherType getType() {
        return type;
    }

    ...

    public StubMatcher matcher() {
        try {
            return matcherMap.get(type).getDeclaredConstructor(StubMatcherConfig.class).newInstance(this);
        } catch (final Exception cause) {
            logger.error("Configuration error. Type: " + type.name() + "; Path: " + path + "; Method: " + method, cause);
        }
        return null;
    }
}

public interface StubMatcher {

    boolean matches(Request request);
}

public class ExactPathMatcher implements StubMatcher {

    private static final Logger logger = LoggerFactory.getLogger(ExactPathMatcher.class);

    private final String path;

    public ExactPathMatcher(final StubMatcherConfig config) {
        this.path = config.getPath();
    }

    @Override
    public boolean matches(final Request request) {
        return request.matchPath().equals(path);
    }

}

0 个答案:

没有答案