Add property to enable/disable Guice just-in-time bindings and log just-in-time bindings usage
This commit is contained in:
committed by
Taylor Wicksell
parent
1e7cbb0e31
commit
368ebc4d36
@@ -70,9 +70,12 @@ class ModuleRegistryConfiguration
|
||||
implements BeanDefinitionRegistryPostProcessor, ApplicationContextAware {
|
||||
|
||||
private static final String SPRING_GUICE_DEDUPE_BINDINGS_PROPERTY_NAME = "spring.guice.dedup";
|
||||
private static final String SPRING_GUICE_AUTOWIRE_JIT_PROPERTY_NAME = "spring.guice.autowireJIT";
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private List<Module> modules;
|
||||
private AtomicBoolean injectorCreated = new AtomicBoolean(false);
|
||||
private boolean enableJustInTimeBinding = true;
|
||||
|
||||
private void createInjector(List<Module> modules,
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
@@ -178,7 +181,7 @@ class ModuleRegistryConfiguration
|
||||
throws BeansException {
|
||||
modules = new ArrayList<Module>(((ConfigurableListableBeanFactory) registry)
|
||||
.getBeansOfType(Module.class).values());
|
||||
modules.add(new SpringModule((ConfigurableListableBeanFactory) registry));
|
||||
modules.add(new SpringModule((ConfigurableListableBeanFactory) registry, enableJustInTimeBinding));
|
||||
Map<Key<?>, Binding<?>> bindings = new HashMap<Key<?>, Binding<?>>();
|
||||
List<Element> elements = Elements.getElements(Stage.TOOL, modules);
|
||||
if (applicationContext.getEnvironment().getProperty(
|
||||
@@ -303,6 +306,8 @@ class ModuleRegistryConfiguration
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
this.enableJustInTimeBinding = applicationContext.getEnvironment()
|
||||
.getProperty(SPRING_GUICE_AUTOWIRE_JIT_PROPERTY_NAME, Boolean.class, true);
|
||||
}
|
||||
|
||||
private static class GuiceInjectorInitializingBeanPostProcessor
|
||||
|
||||
@@ -67,6 +67,10 @@ class GuiceAutowireCandidateResolver extends ContextAnnotationAutowireCandidateR
|
||||
try {
|
||||
beanFactory.doResolveDependency(descriptor, beanName, null, null);
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
if (e.getResolvableType() != null) {
|
||||
logger.info(String.format("Use just in time binding for %s in bean: %s",
|
||||
e.getResolvableType().getType().getTypeName(), beanName));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.isLazy(descriptor);
|
||||
|
||||
@@ -73,12 +73,23 @@ public class SpringModule extends AbstractModule {
|
||||
|
||||
private Provider<ConfigurableListableBeanFactory> beanFactoryProvider;
|
||||
|
||||
private boolean enableJustInTimeBinding = true;
|
||||
|
||||
public SpringModule(ApplicationContext context) {
|
||||
this((ConfigurableListableBeanFactory) context.getAutowireCapableBeanFactory());
|
||||
this(context, true);
|
||||
}
|
||||
|
||||
public SpringModule(ApplicationContext context, boolean enableJustInTimeBinding) {
|
||||
this((ConfigurableListableBeanFactory) context.getAutowireCapableBeanFactory(), enableJustInTimeBinding);
|
||||
}
|
||||
|
||||
public SpringModule(ConfigurableListableBeanFactory beanFactory) {
|
||||
this(beanFactory, true);
|
||||
}
|
||||
|
||||
public SpringModule(ConfigurableListableBeanFactory beanFactory, boolean enableJustInTimeBinding) {
|
||||
this.beanFactory = beanFactory;
|
||||
this.enableJustInTimeBinding = enableJustInTimeBinding;
|
||||
}
|
||||
|
||||
public SpringModule(Provider<ConfigurableListableBeanFactory> beanFactoryProvider) {
|
||||
@@ -95,10 +106,12 @@ public class SpringModule extends AbstractModule {
|
||||
beanFactory.getBeansOfType(ProvisionListener.class).values()
|
||||
.toArray(new ProvisionListener[0]));
|
||||
}
|
||||
if (beanFactory instanceof DefaultListableBeanFactory) {
|
||||
((DefaultListableBeanFactory) beanFactory)
|
||||
.setAutowireCandidateResolver(new GuiceAutowireCandidateResolver(
|
||||
binder().getProvider(Injector.class)));
|
||||
if (enableJustInTimeBinding) {
|
||||
if (beanFactory instanceof DefaultListableBeanFactory) {
|
||||
((DefaultListableBeanFactory) beanFactory)
|
||||
.setAutowireCandidateResolver(new GuiceAutowireCandidateResolver(
|
||||
binder().getProvider(Injector.class)));
|
||||
}
|
||||
}
|
||||
if (beanFactory.getBeanNamesForType(GuiceModuleMetadata.class).length > 0) {
|
||||
this.matcher = new CompositeTypeMatcher(
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
{"properties": [{
|
||||
"name": "spring.guice.dedup",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "When using `@EnableGuiceModules`, if a Spring Bean and a Guice Binding both exist for the same type and Qualifier, the Spring Bean will be kept and the Guice Binding discarded.",
|
||||
"defaultValue": "false"
|
||||
}]}
|
||||
{
|
||||
"properties": [
|
||||
{
|
||||
"name": "spring.guice.dedup",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "When using `@EnableGuiceModules`, if a Spring Bean and a Guice Binding both exist for the same type and Qualifier, the Spring Bean will be kept and the Guice Binding discarded.",
|
||||
"defaultValue": "false"
|
||||
},
|
||||
{
|
||||
"name": "spring.guice.autowireJIT",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "When enabled, beans without explicit definitions will be created using Guice just-in-time bindings. Otherwise, it will fail with UnsatisfiedDependencyException.",
|
||||
"defaultValue": "true"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.springframework.guice;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.guice.annotation.EnableGuiceModules;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class JustInTimeBindingTests {
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
System.clearProperty("spring.guice.autowireJIT");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void springWithJustInTimeBinding() {
|
||||
System.setProperty("spring.guice.autowireJIT", "true");
|
||||
assertNotNull(springGetFoo());
|
||||
}
|
||||
|
||||
@Test(expected = UnsatisfiedDependencyException.class)
|
||||
public void springWithoutJustInTimeBinding() {
|
||||
System.setProperty("spring.guice.autowireJIT", "false");
|
||||
springGetFoo();
|
||||
}
|
||||
|
||||
private Foo springGetFoo() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class);
|
||||
context.getDefaultListableBeanFactory().registerBeanDefinition(Foo.class.getSimpleName(), new RootBeanDefinition(Foo.class));
|
||||
return context.getBean(Foo.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableGuiceModules
|
||||
static class ModulesConfig {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class Service {
|
||||
}
|
||||
|
||||
public static class Foo {
|
||||
|
||||
Service service;
|
||||
|
||||
@Inject
|
||||
public Foo(Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user