Switch to provider instead of autowired

This commit is contained in:
Dave Syer
2023-02-03 14:32:00 +00:00
parent 1726fa780a
commit 340234ebbf
3 changed files with 23 additions and 19 deletions

View File

@@ -22,7 +22,6 @@ import com.google.inject.Injector;
import com.google.inject.Key;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Convenience class used to map a Guice {@link Provider} to a Spring bean.
@@ -38,22 +37,18 @@ class GuiceFactoryBean<T> implements FactoryBean<T> {
private final boolean isSingleton;
private Injector injector;
private final Provider<Injector> injector;
GuiceFactoryBean(Class<T> beanType, Key<T> key, boolean isSingleton) {
GuiceFactoryBean(Class<T> beanType, Key<T> key, boolean isSingleton, Provider<Injector> injector) {
this.beanType = beanType;
this.key = key;
this.isSingleton = isSingleton;
}
@Autowired
void setInjector(Injector injector) {
this.injector = injector;
}
@Override
public T getObject() throws Exception {
return (T) this.injector.getInstance(this.key);
return (T) this.injector.get().getInstance(this.key);
}
@Override

View File

@@ -59,7 +59,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
@@ -128,7 +127,9 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
List<Module> modules = new ArrayList<>(
((ConfigurableListableBeanFactory) registry).getBeansOfType(Module.class).values());
modules.add(new SpringModule((ConfigurableListableBeanFactory) registry, this.enableJustInTimeBinding));
SpringModule module = new SpringModule((ConfigurableListableBeanFactory) registry,
this.enableJustInTimeBinding);
modules.add(module);
Map<Key<?>, Binding<?>> bindings = new HashMap<Key<?>, Binding<?>>();
List<Element> elements = Elements.getElements(Stage.TOOL, modules);
List<Message> errors = elements.stream().filter((e) -> e instanceof Message).map((e) -> (Message) e)
@@ -156,7 +157,7 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor
extractPrivateElements(bindings, (PrivateElements) e);
}
}
mapBindings(bindings, registry);
mapBindings(bindings, registry, module);
// Register the injector initializer
RootBeanDefinition beanDefinition = new RootBeanDefinition(GuiceInjectorInitializer.class);
@@ -172,7 +173,7 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor
}
private void mapBindings(Map<Key<?>, Binding<?>> bindings, BeanDefinitionRegistry registry) {
private void mapBindings(Map<Key<?>, Binding<?>> bindings, BeanDefinitionRegistry registry, SpringModule module) {
Stage stage = this.applicationContext.getEnvironment().getProperty(SPRING_GUICE_STAGE_PROPERTY_NAME,
Stage.class, Stage.PRODUCTION);
boolean ifLazyInit = stage.equals(Stage.DEVELOPMENT);
@@ -213,11 +214,12 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor
Class<? extends Annotation> annotationType = key.getAnnotationType();
RootBeanDefinition bean = new RootBeanDefinition(GuiceFactoryBean.class);
ConstructorArgumentValues args = new ConstructorArgumentValues();
args.addIndexedArgumentValue(0, typeLiteral.getRawType());
args.addIndexedArgumentValue(1, key);
args.addIndexedArgumentValue(2, Scopes.isSingleton(binding));
bean.setConstructorArgumentValues(args);
bean.setInstanceSupplier(() -> {
@SuppressWarnings({ "rawtypes", "unchecked" })
GuiceFactoryBean factory = new GuiceFactoryBean(typeLiteral.getRawType(), key,
Scopes.isSingleton(binding), module.getInjector());
return factory;
});
bean.setTargetType(ResolvableType.forType(typeLiteral.getType()));
if (!Scopes.isSingleton(binding)) {
bean.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);

View File

@@ -83,6 +83,8 @@ public class SpringModule extends AbstractModule {
private boolean enableJustInTimeBinding = true;
private Provider<Injector> injector;
public SpringModule(ApplicationContext context) {
this(context, true);
}
@@ -109,14 +111,15 @@ public class SpringModule extends AbstractModule {
if (this.beanFactory == null) {
this.beanFactory = this.beanFactoryProvider.get();
}
this.injector = binder().getProvider(Injector.class);
if (this.beanFactory.getBeanNamesForType(ProvisionListener.class).length > 0) {
binder().bindListener(Matchers.any(), this.beanFactory.getBeansOfType(ProvisionListener.class).values()
.toArray(new ProvisionListener[0]));
}
if (this.enableJustInTimeBinding) {
if (this.beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) this.beanFactory).setAutowireCandidateResolver(
new GuiceAutowireCandidateResolver(binder().getProvider(Injector.class)));
((DefaultListableBeanFactory) this.beanFactory)
.setAutowireCandidateResolver(new GuiceAutowireCandidateResolver(this.injector));
}
}
if (this.beanFactory.getBeanNamesForType(GuiceModuleMetadata.class).length > 0) {
@@ -126,6 +129,10 @@ public class SpringModule extends AbstractModule {
bind(this.beanFactory);
}
public Provider<Injector> getInjector() {
return this.injector;
}
private void bind(ConfigurableListableBeanFactory beanFactory) {
for (String name : beanFactory.getBeanDefinitionNames()) {
BeanDefinition definition = beanFactory.getBeanDefinition(name);