Ответ 1
Guice не разрешает AOP для экземпляров, не созданных Guice: Ограничения AOP в Guice
"Экземпляры должны быть созданы Guice конструктором @Inject-annotated или no-argument"
Это означает, что экземпляры, созданные с поставщиком, не будут кандидатами для АОП.
С другой стороны, до тех пор, пока ваш провайдер будет создан Guice в соответствии с указанными условиями, ваш поставщик может быть кандидатом на АОП.
Вот пример, который демонстрирует это:
AOP Аннотация:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
@interface AOPExample {}
Provider:
public class ExampleProvider implements Provider<Example> {
@AOPExample
public Example get() {
System.out.println("Building...");
return new Example();
}
}
Целевой пример:
public class Example {
@AOPExample
public void tryMe() {
System.out.println("example working...");
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Модуль:
public class ExampleModule extends AbstractModule {
@Override
protected void configure() {
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AOPExample.class), new LoggingAOP());
bind(Example.class).toProvider(ExampleProvider.class);
}
}
Тестовый код:
public class Test {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TestModule());
ExampleProvider exampleProvider = injector.getInstance(ExampleProvider.class);
Example example = exampleProvider.get();
example.tryMe();
Example directExample = injector.getInstance(Example.class);
directExample.tryMe();
}
}
Выход теста:
start
Building...
end took: 3
example working...
start
Building...
end took: 0
example working...
Обратите внимание, что "пример работы..." не окружен кодом таймера. Однако Provider.get( "Создать..." ).
Если ваш вопрос: может ли перехватчик (новый INTERCEPTOR()) быть предоставлен через поставщика Guice, ответ - нет. Самое близкое, что вы можете получить к этой функции, вызывает метод requestInjection() в модуле configure. Это введет ваш Interceptor с соответствующим кодом. Из вашего перехватчика вы можете использовать Провайдеры, чтобы избежать каких-либо накладных расходов, которые вызывают медленность во время запуска.
Вот что я имею в виду:
Модуль:
public class TestModule extends AbstractModule {
@Override
protected void configure() {
bind(String.class).toInstance("One");
bind(String.class).annotatedWith(Names.named("two")).toInstance("Two");
LoggingAOP loggingAOP = new LoggingAOP();
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AOPExample.class), loggingAOP);
requestInjection(loggingAOP);
bind(Example.class).toProvider(ExampleProvider.class);
}
}
перехватчик:
public class LoggingAOP implements MethodInterceptor {
@Inject
private Provider<SomethingThatTakesALongTimeToInit> provider;
public Object invoke(MethodInvocation invocation) throws Throwable {
provider.get()...
System.out.println("start");
long start = System.currentTimeMillis();
Object value = invocation.proceed();
System.out.println("end took: " + (System.currentTimeMillis() - start));
return value;
}
}
Надеюсь, это ответит на ваш вопрос.