#java #dependency-injection #guice
#java #зависимость-внедрение #guice
Вопрос:
Я использую прослушиватель инъекций, чтобы выполнить инициализацию после введения. Допустим, я создаю эту аннотацию:
@Retention(RetentionPolicy.RUNTIME)
public static @interface PrintValue {
String value() default "";
}
Теперь я хочу, чтобы каждый раз объект PrintValue
класса выводил это значение. Например, если класс такой:
@PrintValue("Something")
public static class Foo {
}
каждый раз, когда вводится Foo, моя инициализация «после введения» заключается в том, чтобы напечатать его значение. Тем не менее, я хочу добавить к этому исключение. Я много чего перепробовал, но мне не удалось этого добиться.
Если класс выглядит так:
@PrintValue("Something else")
public static class Bar {
@Inject
public Bar(Foo foo) {
System.out.println("Constructed a bar");
}
}
Я не хочу, чтобы инициирование Foo post имело место, потому что объект, который запрашивает foo, является объектом PrintValue
класса. Другими словами, это «Что-то другое» «@Переопределяет» PrintValue
Foo . Единственный способ, который я могу придумать, чтобы добиться этого, — это попасть в слушателя, класс объекта, который запрашивал зависимость. Посмотрите Полный пример и обратите внимание на комментарий в InjectionListener
:
public class GuiceListener {
@Retention(RetentionPolicy.RUNTIME)
public static @interface PrintValue {
String value() default "";
}
@PrintValue("Something")
public static class Foo {
}
@PrintValue("Something else")
public static class Bar {
@Inject
public Bar(Foo foo) {
System.out.println("Constructed a bar");
}
}
public static void main(String[] args) {
Module module = new AbstractModule() {
@Override
protected void configure() {
bind(Foo.class);
bind(Bar.class);
bindListener(Matchers.any(), new TypeListener() {
@Override
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
if (type.getRawType().isAnnotationPresent(PrintValue.class)) {
encounter.register(new PrintValueInjectionListener());
}
}
});
}
};
Injector injector = Guice.createInjector(module);
Foo foo = injector.getInstance(Foo.class);
Bar bar = injector.getInstance(Bar.class);
}
public static class PrintValueInjectionListener implements InjectionListener<Object> {
@Override
public void afterInjection(Object injectee) {
//get here who asked (its class) the injectee ??
PrintValue printValue = injectee.getClass().getAnnotation(PrintValue.class);
System.out.println(printValue.value());
}
}
}
Если я запускаю это, я получаю в качестве вывода:
Something
Something
Constructed a bar
Something else
Но результат, который я хочу, это:
Something (printed because of the Foo foo = injector.getInstance(Foo.class))
Constructed a bar
Something else
Возможно ли это?
Ответ №1:
Вы можете сделать это с ProvisionListener.getDependencyChain()
помощью . Сейчас это устарело, но они приводят несколько примеров замены.