Restore support for Guice PrivateModule's

See #32
This commit is contained in:
Taylor Wicksell
2018-02-28 11:37:40 -06:00
committed by Dave Syer
parent aae2e1fc47
commit e94c94837f
2 changed files with 115 additions and 1 deletions

View File

@@ -29,6 +29,7 @@ import com.google.inject.name.Named;
import com.google.inject.spi.Element;
import com.google.inject.spi.ElementSource;
import com.google.inject.spi.Elements;
import com.google.inject.spi.PrivateElements;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@@ -87,7 +88,7 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor
if (injector == null) {
injector = Guice.createInjector(modules);
}
beanFactory.registerResolvableDependency(Injector.class, injector);
beanFactory.registerSingleton("injector", injector);
}
private void mapBindings(Map<Key<?>, Binding<?>> bindings,
@@ -138,6 +139,8 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor
if (e instanceof Binding) {
Binding<?> binding = (Binding<?>) e;
bindings.put(binding.getKey(), binding);
} else if (e instanceof PrivateElements) {
extractPrivateElements(bindings, (PrivateElements) e);
}
}
mapBindings(bindings, registry);
@@ -148,6 +151,18 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor
applicationContext.publishEvent(new CreateInjectorSignalEvent());
}
private void extractPrivateElements(Map<Key<?>, Binding<?>> bindings, PrivateElements privateElements) {
List<Element> elements = privateElements.getElements();
for (Element e : elements) {
if (e instanceof Binding && privateElements.getExposedKeys().contains(((Binding<?>) e).getKey())) {
Binding<?> binding = (Binding<?>) e;
bindings.put(binding.getKey(), binding);
} else if (e instanceof PrivateElements) {
extractPrivateElements(bindings, (PrivateElements) e);
}
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {

View File

@@ -0,0 +1,99 @@
package org.springframework.guice;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.guice.PrivateModuleTests.SomeInterface;
import org.springframework.guice.PrivateModuleTests.SomePrivateModule;
import org.springframework.guice.annotation.EnableGuiceModules;
import com.google.inject.AbstractModule;
import com.google.inject.ConfigurationException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.PrivateModule;
import com.google.inject.name.Names;
public class PrivateModuleTests {
private static AnnotationConfigApplicationContext context;
@BeforeClass
public static void init() {
context = new AnnotationConfigApplicationContext(PrivateModuleTestConfig.class);
}
@AfterClass
public static void cleanup() {
if(context != null) {
context.close();
}
}
@Test
public void verifyPrivateModulesCanExposeBindings() {
Injector injector = context.getBean(Injector.class);
SomeInterface injectorProvidedPrivateBinding = injector.getInstance(Key.get(SomeInterface.class, Names.named("exposed")));
assertNotNull(injectorProvidedPrivateBinding);
SomeInterface springProvidedPrivateBinding = context.getBean(SomeInterface.class);
assertNotNull(springProvidedPrivateBinding);
SomeInterface namedPrivateBinding = context.getBean("exposed",SomeInterface.class);
assertNotNull(namedPrivateBinding);
assertEquals(injectorProvidedPrivateBinding, springProvidedPrivateBinding);
assertEquals(injectorProvidedPrivateBinding, namedPrivateBinding);
String beanDependingOnPrivateBinding = context.getBean("somethingThatWantsAPrivateBinding", String.class);
assertNotNull(beanDependingOnPrivateBinding);
assertEquals("foo", beanDependingOnPrivateBinding);
}
@Test(expected=ConfigurationException.class)
public void verifyPrivateModulesPrivateBindingsAreNotExposedViaInjector() {
Injector injector = context.getBean(Injector.class);
injector.getInstance(Key.get(SomeInterface.class, Names.named("notexposed")));
}
@Test(expected=NoSuchBeanDefinitionException.class)
public void verifyPrivateModulesPrivateBindingsAreNotExposedViaSpring() {
context.getBean("notexposed",SomeInterface.class);
}
public static interface SomeInterface {}
public static class SomePrivateBinding implements SomeInterface {}
public static class SomePrivateModule extends PrivateModule {
@Override
protected void configure() {
bind(SomeInterface.class).annotatedWith(Names.named("exposed")).to(SomePrivateBinding.class).asEagerSingleton();
bind(SomeInterface.class).annotatedWith(Names.named("notexposed")).to(SomePrivateBinding.class).asEagerSingleton();
expose(SomeInterface.class).annotatedWith(Names.named("exposed"));
}
}
}
@EnableGuiceModules
@Configuration
class PrivateModuleTestConfig {
@Bean
public String somethingThatWantsAPrivateBinding(SomeInterface privateBinding) {
return "foo";
}
@Bean
public Module module() {
return new AbstractModule() {
@Override
protected void configure() {
install(new SomePrivateModule());
}
};
}
}