首页 > 解决方案 > 带有构造函数的服务加载器

问题描述

所以,这是我的结构

interface FactoryService {
    Foo createFoo(int a, String b);
}

@AutoService(FactoryService.class)
class SomeFactory implements FactoryService {
    public Foo createFoo(int a, String b) {
        // How to implement service loader here, which loads Foo
    }
}

interface Foo {
    void opsForFoo(InputStream s, OutputStream o)
}

class FooImpl implements Foo {
    // Constructor
    public FooImpl(int a, String b) {}
    public void opsForFoo(InputStream s, OutputStream o) {
        // perform operation here
    }
}

如何在SomeFactory课堂上实现 ServiceLoader?我遇到的问题是FooImpl从构造函数中获取两个值。我可以这样做new FooImpl(a, b),但它正确吗?展望未来,可能会有其他类实现Foo

标签: javaoop

解决方案


服务加载器基础结构的要点是,您可以定义任意数量的类,这些类是您正在为其创建服务加载器的任何东西的实现,它们可以位于类路径中的任何位置。

例如,在您的示例中,您将服务加载“FactoryService”(不是 foo!),因此,您的代码可以提供任意数量的 FactoryService 实现,并且无论做什么服务加载都将获得每个此类的 1 个实例您设置的 FactoryService 类。在这里,您正在设置一个这样的类,称为“SomeFactory”。

这个特定的 FactoryService 变体(您的“SomeFactory”)将在被调用时(在其createFoo方法被调用时)返回 FooImpl 的一个实例。

如果有一天,Foo 有不同的 impl,你有两个选择:

[1] 扩展您的 SomeFactory 类以根据您想要的任何内容返回这个不同的 impl(毕竟,这是代码,没有限制)。例如:return a < 0 ? new NegativeFooImpl(Math.abs(a), b) : new PositiveFooImpl(a, b);

[2] 创建第二个类,它也实现了 FactoryService。

这里的总体布局FactoryService有点奇怪:假设有 10 个工厂服务,这里的想法是什么?一些请求进来了,无论是在为 factoryservice 调用所有 10 个服务,产生 10 个 foo,然后.. 选择一个?大概FactoryService接口需要一些javadoc,比如:/** If a and b are such that this call is not for you, return null. The code that loads foos will go with the Foo value returned by the first implementation of FactoryService called that returns non-null. */

例如,最后一个看起来有点像:

public class FooMaker {
    ServiceLoader<FactoryService> fooFactories = ServiceLoader.load(FactoryService.class);

    public Foo createAFoo(int a, String b) {
        for (FactoryService factory : fooFactories) {
            Foo foo = factory.createFoo(a, b);
            if (foo != null) return foo;
        }
        return null;
    }
}

推荐阅读