это ответ на основе MultiBindings в виде. Общее: вы можете привязать несколько реализаций к данному интерфейсу, а затем ввести набор реализаций.
То, что я собираюсь сделать, - это привязать все мои проверки пароля, ввести их, а затем использовать этот набор, чтобы определить, что делать.
Это полный работает пример:
класс
public class TestMultiBinding {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
Multibinder<PasswordChecker> multiBinder = Multibinder.newSetBinder(binder(), PasswordChecker.class);
multiBinder.addBinding().to(BusinessChecker.class);
multiBinder.addBinding().to(ClientChecker.class);
bind(Test.class).in(Singleton.class);
}
});
Test test = injector.getInstance(Test.class);
test.verifyPassword("hello", Person.P1);
test.verifyPassword("hello", Person.P2);
}
public static class Test {
private Set<PasswordChecker> checkers;
@Inject
public Test(final Set<PasswordChecker> checker) {
this.checkers = checker;
}
public void verifyPassword(final String pass, final Person p) {
getPasswordChecker(p).check(pass);
}
public PasswordChecker getPasswordChecker(final Person p) {
Optional<PasswordChecker> checker = checkers.stream().filter(c -> c.isApplicable(p)).findFirst();
if(checker.isPresent()) {
return checker.get();
}
return null; // or default
}
}
public static interface PasswordChecker {
public void check(String s);
boolean isApplicable(Person P);
}
public static class BusinessChecker implements PasswordChecker {
@Override
public void check(String s) {
System.out.println("User Business Checker");
}
@Override
public boolean isApplicable(Person P) {
return P.equals(Person.P1);
}
}
public static class ClientChecker implements PasswordChecker {
@Override
public void check(String s) {
System.out.println("User Client Checker");
}
@Override
public boolean isApplicable(Person P) {
return P.equals(Person.P2);
}
}
public enum Person {
P1, P2;
}
}
Тест ваш пример. Он принимает пароль и перечисление Person.
Каждый PasswordChecker реализует метод под названием «isApplicable», чтобы определить, может ли данное лицо использовать эту проверку. Альтернативно, во время инъекции вы можете сопоставить PasswordChecker с правильным человеком (используя методы stream.collect (Collectors.toMap (...))). Таким образом, вам нужно будет только просмотреть хэш-карту, чтобы получить правильную реализацию.
В моем модуле я определяю многосвязывание для паролей. Я добавляю привязки к нему.
Остальное вы можете видеть.
Вызов мой код выведет:
User Business Checker
User Client Checker
Я надеюсь, что это то, что вы искали :) дайте мне знать!
Artur
Ваш объект Person - объект json, в который вы проходите? – pandaadb
Это не означает, что для простоты можно предположить, что человек является перечислением, на котором можно оценить if. Проблема заключается в том, как динамически изменять привязки guice. – PKuhn
Вы можете использовать multibindings, связывать X количество PasswordChecker и вместо метода isXXXClient, у вас есть метод getPasswordChecker (Person), который возвращает правильную проверку пароля – pandaadb