是否可以加载基于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);
}
}