在运行时基于提供的依赖关系动态创建Java类的实现

前端之家收集整理的这篇文章主要介绍了在运行时基于提供的依赖关系动态创建Java类的实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试根据运行时在类路径上可用的类来确定创建类的新实例的最佳方法

例如,我有一个需要在多个类中解析JSON响应的库。该库具有以下界面:

JsonParser.java:

public interface JsonParser {
    <T> T fromJson(String json,Class<T> type);
    <T> String toJson(T object);
}

该类有多个实现,即GsonJsonParser,JacksonJsonParser,Jackson2JsonParser,目前,库的用户需要根据他们在项目中包含的库来“选择”使用它们的实现。例如:

JsonParser parser = new GsonJsonParser();
SomeService service = new SomeService(parser);

我想要做的是动态地选择类路径中的哪个库,并创建正确的实例,以便图书馆的用户不必考虑它(甚至必须知道内部实现另一个类解析JSON)。

我正在考虑类似于以下内容

try {
    Class.forName("com.google.gson.Gson");
    return new GsonJsonParser();
} catch (ClassNotFoundException e) {
    // Gson isn't on classpath,try next implementation
}

try {
    Class.forName("com.fasterxml.jackson.databind.ObjectMapper");
    return new Jackson2JsonParser();
} catch (ClassNotFoundException e) {
    // Jackson 2 was not found,try next implementation
}

// repeated for all implementations

throw new IllegalStateException("You must include either Gson or Jackson on your classpath to utilize this library");

这将是一个适当的解决方案吗?这似乎是一个黑客,以及使用异常来控制流。

有没有更好的方法来做到这一点?

基本上你想创建自己的JsonParserFactory。我们可以看到它在 Spring Boot framework中的实现方式:
public static JsonParser getJsonParser() {
    if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",null)) {
        return new JacksonJsonParser();
    }
    if (ClassUtils.isPresent("com.google.gson.Gson",null)) {
        return new GsonJsonParser();
    }
    if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml",null)) {
        return new YamlJsonParser();
    }

    return new BasicJsonParser();
}

所以你的做法和这个几乎是一样的,除了使用ClassUtils.isPresent method

猜你在找的设计模式相关文章