Подход Guice @annotations похож на подход Guice MapBinder
Я новичок в Guice DI. И я хотел бы уточнить мой сценарий.
Проще говоря, есть ли замена MapBinder через Guice @annotations?
Мой сценарий:
Interface A{}
Class A1 implements A{}
Class A2 implements A{}
Я хотел бы внедрить класс реализации A следующим образом,
if(param = One) then Inject A1 to A
if(param = Two) then Inject A2 to A
Я понимаю, что вышеупомянутое может быть сделано с MapBinder, но я хотел бы сделать это с помощью аннотаций следующим образом:
Class A1 implements A
{
@Inject(param = One)
A1(){}
}
Class A2 implements A
{
@Inject(param = Two)
A2(){}
}
Таким образом, создание класса с аннотациями может автоматически выбирать и вводить класс в зависимости от параметра (Один или Два).
Поскольку @Inject не может принимать параметры, переопределение @Inject поможет в этом сценарии? если да, то как нам это сделать?
Или этот сценарий может быть реализован только с помощью привязки с использованием MapBinder (причина, по которой я не хотел бы использовать связыватель, заключается в том, что мы хотели бы явно определить карту привязки пары ключ-значение, но с помощью аннотаций просто аннотируйте класс реализации с помощью params - проще в обслуживании).
Заранее спасибо.
2 ответа
Чтобы ответить на ваше последующее квестино, я считаю, что то, что вы ищете, называется инъекцией. Смотрите этот пример:
public class GuiceNamedTest extends AbstractModule {
public static void main(String[] args) {
Injector i = Guice.createInjector(new GuiceNamedTest());
i.getInstance(InstaceOne.class);
i.getInstance(InstaceTwo.class);
}
@Override
protected void configure() {
Bean beanOne = new Bean();
beanOne.name = "beanOne";
Bean beanTwo = new Bean();
beanTwo.name = "beanTwo";
bind(Bean.class).annotatedWith(Names.named("one")).toInstance(beanOne);
bind(Bean.class).annotatedWith(Names.named("two")).toInstance(beanTwo);
bind(InstaceOne.class);
bind(InstaceTwo.class);
}
public static class Bean {
String name;
}
public static interface A {}
public static class InstaceOne implements A {
@javax.inject.Inject
public InstaceOne(@Named("one") Bean b1) {
System.out.println(b1.name);
}
}
public static class InstaceTwo implements A {
@javax.inject.Inject
public InstaceTwo(@Named("two") Bean b1) {
System.out.println(b1.name);
}
}
}
Здесь я использую annotatedWith
назвать мои экземпляры, обработанные обманкой. Один из них соответствует строке "один", а другой - "два", аналогично вашему примеру.
Я могу тогда, в моих реализациях A
есть конкретные инъекции этих бобов с использованием @Named
аннотаций.
Результат при выполнении кода выше:
beanOne
beanTwo
Как видите, он ввел правильный экземпляр моего компонента в правильную реализацию.
Надеюсь, это поможет,
Артур
Из JLS, §9.6,
"В силу синтаксиса AnnotationTypeDeclaration, объявление типа аннотации не может быть универсальным, и предложение extends не допускается.
"Следствием того факта, что тип аннотации не может явно объявить суперкласс или суперинтерфейс, является то, что подкласс или субинтерфейс типа аннотации никогда не является сам по себе типом аннотации. Аналогично, java.lang.annotation.Annotation сам по себе не является типом аннотации."
Таким образом, нет, "переопределение [sic]" не поможет, потому что никакой расширяющий тип не может быть типом аннотации.