Я все еще хочу попробовать это в большем масштабе с нашей системой app + build, но более высокие приоритеты продолжают отодвигать ее на второй план. Это кажется хорошим способом загрузки модулей Guice и позволяет избежать распространенной жалобы на «жестко заданную конфигурацию». Отдельные свойства конфигурации редко изменяются сами по себе, но у вас почти всегда будет набор профилей, обычно для разных сред (Debug, Production и т. Д.).
ServiceLoader позволяет вам получить список всех реализаций, определенных как сервис для данного типа. Соединив это с Guice, вы получите:
import java.util.ServiceLoader;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
public class ModuleLoader<M extends Module> extends AbstractModule {
private final Class<M> type;
public ModuleLoader(Class<M> type) {
this.type = type;
}
public static <M extends Module> ModuleLoader<M> of(Class<M> type) {
return new ModuleLoader<M>(type);
}
@Override
protected void configure() {
ServiceLoader<M> modules = ServiceLoader.load(type);
for (Module module : modules) {
install(module);
}
}
}
Пример использования (в качестве динамического загрузчика сервлета в проекте guice-servlet):
import com.google.inject.servlet.ServletModule;
public class ServletLoader extends GuiceServletContextListener {
@Override
protected final Injector getInjector() {
return Guice.createInjector(ModuleLoader.of(ServletModule.class);
}
}
Службы (упакованные в виде модулей) будут упакованы в отдельные файлы JAR. В каждом из них вы определяете класс (ы) в метаданных:
Within servlets.jar: META-INF/services/com.google.inject.Module
com.example.webapps.MyServletModuleA
com.example.webapps.MyServletModuleB
Поскольку мы используем Maven, мы считаем, что это было бы идеально, так как мы могли бы использовать различные реализации во время выполнения через зависимости профиля. Кто-нибудь использует Guice, как это?
Если нет, не стесняйтесь использовать этот пример и посмотрите, как он работает для вас. (ServiceLoader поддерживается только в JDK6 +)