Class GeneratorAnchorModule
- java.lang.Object
-
- com.google.inject.AbstractModule
-
- ru.vyarus.guice.ext.core.generator.anchor.GeneratorAnchorModule
-
- All Implemented Interfaces:
com.google.inject.Module
public class GeneratorAnchorModule extends com.google.inject.AbstractModuleSupport module used to tie dynamic binding for generated class (generated withDynamicClassProvider) to exact injector in injectors hierarchy. Also, allows using JIT resolution for generated classes in private modules (without binding them explicitly).Situation without this module: suppose we have root and child injector and aop interceptors (which must intercept generated abstract method calls) are registered in child module. If abstract bean resolved with guice JIT (
@ProvidedBy(DynamicClassProvider.class)then it's binding will be created in upper-most injector: root injector. As a result, calling any abstract method will fail, because interceptors are not present in root module (only in child module).To fix this problem we need to "tie" generated class binding to child injector. Guice will not bubble it up only if it depends on some other bean located in child injector. For this purpose, module registers dummy service
AnchorBeanwhich is only required to "hold" generated been in child injector. Also, provider classes are explicitly bound to be able to operate with child injector in provider. BothDynamicClassProviderandDynamicSingletonProviderwill check first if anchor bean is available in current injector and inject dependency on this bean into generated class (add new constructor parameter for abstract class with constructor and generate new constructor for interface implementation or abstract class without constructor).Also, module will prevent improper guice injector usage. For example, anchor module registered in child injector and some service DynService depends (injects) on abstract class annotated with
ProvidedBy(DynamicClassProvider.class). If DynService is not bound in child injector and we try to create instance of (using JIT binding) it from root injector, then guice will try to obtain DynamicClassProvider in root context and fail with duplicate binding definition (without anchor module, everything would pass, but aop will not work, because it was registered in child injector).Example usage:
Injector childInjector = Guice.createInjector() // root injector .createChildInjector(new GeneratorAnchorModule(), new MyAopModule()); // JIT binding for MyAbstractService (generated class) will be in child injector and so aop will work childInjector.getInstance(MyAbstractService.class).someAMethodHandledWithAop();Private module example:
public class MyPrivateModule extends PrivateModule { protected void configure() { install(new MyAopModule()); install(new GeneratorAnchorModule()); } @Provides @Exposed @Named("myBean") MyAbstractBean provide(MyAbstractBean bean) { return bean; } } Injector injector = Injector.createModule(new MyPrivateModule()); // obtain exposed named instance outside of private module // note that abstract bean was not bound and resolved with JIT injector.getInstance(Key.get(MyAbstractBean.class, Names.named("myBean")))- Since:
- 21.09.2016
-
-
Constructor Summary
Constructors Constructor Description GeneratorAnchorModule()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected voidconfigure()-
Methods inherited from class com.google.inject.AbstractModule
addError, addError, addError, bind, bind, bind, bindConstant, binder, bindInterceptor, bindListener, bindListener, bindScope, configure, convertToTypes, currentStage, getMembersInjector, getMembersInjector, getProvider, getProvider, install, requestInjection, requestStaticInjection, requireBinding, requireBinding
-
-