gpt4 book ai didi

java - 具有运行时确定的构造函数参数的部分 Autowiring Spring 原型(prototype) bean

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:20:06 25 4
gpt4 key购买 nike

ConstructorResolver.autowireConstructor(...) 的 javadoc 说

Also applied if explicit constructor argument values are specified, matching all remaining arguments with beans from the bean factory.

但我无法让它工作。我得到一个 BeanCreationException:

Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)

在这个例子中,我有一个带有构造函数的 bean,它采用 Spring beans 以及一个 String 和一个仅在运行时才知道的 int

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class BeanWithRuntimeDependencies {

public final DependencyA dependencyA;
public final DependencyB dependencyB;
public final String myString;
public final int myInt;

public BeanWithRuntimeDependencies(
DependencyA dependencyA, DependencyB dependencyB,
String myString, int myInt) {
this.dependencyA = dependencyA;
this.dependencyB = dependencyB;
this.myString = myString;
this.myInt = myInt;
}

}

@Component
public class DependencyA { /* ... */ }

@Component
public class DependencyB { /* ... */ }

和我的测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class PrototypeBeanConstructorsApplicationTests {

@Autowired private ApplicationContext context;

@Autowired private DependencyA dependencyA;

@Autowired private DependencyB dependencyB;

@Test
public void getBeanFromContext() {
BeanWithRuntimeDependencies bean =
context.getBean(BeanWithRuntimeDependencies.class, "runtime string", 10);
assertNotNull(bean);
assertEquals(dependencyA, bean.dependencyA);
assertEquals(dependencyB, bean.dependencyB);
assertEquals("runtime string", bean.myString);
assertEquals(10, bean.myInt);
}

}

ConstructorResolver.autowireConstructor(...)的源码有注释:

// Explicit arguments given -> arguments length must match exactly.

这似乎与其 javadoc 相矛盾。

这有可能吗?我做错了什么?

最佳答案

看起来不可能按照您的方式进行。

其实情况很奇怪。根据 ConstructorResolver.autowireConstructor(...)(源代码行 #207)中的下一个片段,Spring 不会将您的构造函数视为调用的候选对象:

...    
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}

正如您正确指出的那样,它确实与 javadoc 声明相矛盾:

...matching all remaining arguments with beans from the bean factory

但是无论如何,实现意味着默认情况下 Spring 无法解析构造函数来实例化此类 bean。而且您必须手动创建工厂方法。像这样的东西:

@Configuration
public class Config{

@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public BeanWithRuntimeDependencies beanWithRuntimeDependencies(String myString, int myInt){
return new BeanWithRuntimeDependencies(dependencyA(), dependencyB(), myString, myInt);
}

@Bean
public DependencyA dependencyA(){
return new dependencyA();
}

@Bean
public DependencyB dependencyB(){
return new dependencyB();
}
}

然后你可以根据需要从上下文中获取bean:

BeanWithRuntimeDependencies bean = 
context.getBean(BeanWithRuntimeDependencies.class, "runtime string", 10);

如果您不想处理配置类和工厂方法,您可以简单地将所需的 bean 传递到 context.getBean() 中。当然,您必须从上下文中获取此 bean:

BeanWithRuntimeDependencies bean = 
context.getBean(BeanWithRuntimeDependencies.class,
context.getBean(DependencyA.class),
context.getBean(DependencyB.class),
"runtime string", 10);

关于java - 具有运行时确定的构造函数参数的部分 Autowiring Spring 原型(prototype) bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42987414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com