Сервисный погрузчик с конструкторами - PullRequest
0 голосов
/ 04 февраля 2019

Итак, вот моя структура

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
    }
}

Как я могу реализовать ServiceLoader в SomeFactory классе?У меня проблема в FooImpl принимает два значения из конструктора.Я мог бы просто сделать new FooImpl(a, b), но правильно ли это?В будущем могут быть другие классы, которые реализуют Foo

1 Ответ

0 голосов
/ 04 февраля 2019

Суть инфраструктуры serviceloader заключается в том, что вы можете определить любое количество классов, которые являются реализациями того, для чего вы делаете serviceloader, и они могут находиться в любом месте пути к классам.

Например, вВ вашем примере вы собираетесь загружать 'FactoryService' (не foo!), поэтому ваш код может обеспечить любое количество реализаций FactoryService, и что бы вы ни делали, загрузка службы получит 1 экземпляр каждого такого класса FactoryService, который вы 'мы настроены.Здесь вы настраиваете один такой класс, называемый SomeFactory.

Этот конкретный вариант FactoryService (ваш SomeFactory) при вызове (при вызове метода createFoo) возвращаетЭкземпляр FooImpl.

Если когда-нибудь существует другое значение Foo, у вас есть 2 варианта:

[1] расширить класс SomeFactory, чтобы возвращать это другое значение в зависимости от того, что выхочу (это код, в конце концов, небо это предел).Например: return a < 0 ? new NegativeFooImpl(Math.abs(a), b) : new PositiveFooImpl(a, b);

[2] создает второй класс, который также реализует FactoryService.

Общая схема FactoryService здесь немного странная: учитывая, что, скажем, есть, 10 factoryservices, в чем здесь идея?Приходит какой-то запрос: что бы ни делало, сервисная загрузка для factoryservice вызывает все 10 сервисов, производит 10 foos, а затем ... выбирает один?Предположительно, для интерфейса 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...