Суть инфраструктуры 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;
}
}