java - Spring DI 中的通用工厂方法

标签 java spring dependency-injection

我想知道为什么在 Spring DI 中以下 bean 定义有效(我使用 bean instantiation with a static factory method 和 Guava 的 Suppliers.ofInstance ):

<bean id="keySupplier" class="com.google.common.base.Suppliers"
    factory-method="ofInstance">
  <constructor-arg>
    <value type="java.lang.String">someReallyLongValue <!-- note line break here -->
    </value>
  </constructor-arg>
</bean>

但这个不是:

<bean id="keySupplier" class="com.google.common.base.Suppliers"
    factory-method="ofInstance">
  <constructor-arg type="java.lang.String" value="someReallyLongValue" />
</bean>

它抛出以下异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepo' defined in class path resource:
(...)
Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.Object]:
Ambiguous factory method argument types - did you specify the correct bean references as factory method arguments?

问题是,在我的例子中,当我使用第一个带有非常长的字符串作为值的 bean 定义时,我的编辑器在字符串的最后一个字符之后换行,这导致 字符串传递时带有额外的空格Suppliers.ofInstance结果它破坏了我的代码。

第二个定义对空格更加严格,但令人惊讶的是,它不起作用(它可能无法处理通用类型,尽管类型在 type 属性中指定)。

我可以强制 Spring 忽略 <value> 中的空格吗?以某种方式标记?

或者我使用 <constructor-arg type="java.lang.String" value="someReallyLongValue" />适本地?或者我应该提出一个问题,因为它是一个 Spring 错误?

我不想对字符串做任何假设(即在这里使用 string.trim())。

最佳答案

根据reference documentation about constructor resolution,两种配置在Spring中不涉及相同的执行路径.失败来自用于 this instanceOf method 的泛型将 Object 声明为方法参数。

Spring 必须完成以下任务才能成功:

  • 根据论据找到合适的方法
  • 通过显式 type 声明或在使用 index 时根据方法参数类型将 XML 文字值转换为 Java 对象

涉及的逻辑在ConstructorArgumentValuesgetArgumentValue 方法以及 getIndexedArgumentValuegetGenericArgumentValue 方法中的持有者。这两种方法都使用测试根据可用信息拒绝 ValueHolder

在第二个配置场景中,使用索引检测并拒绝值,因为所需类型 StringObject 不完全匹配。此测试使用 ClassUtils.matchesTypeName 完成它不检查类型层次结构。

在第一个配置场景中,值持有者准备好一个 String 对象并且通用参数机制同意,因为该值可分配给检测到的方法参数类型。

从理论上讲,以下表达式应该有效,因为提供了类型以根据值生成对象,并提供了索引以避免任何猜测,即使只有一个方法匹配也是如此。

   <constructor-arg index="0" type="java.lang.String" value="queueName" />

不幸的是,它没有改善任何东西,仍然使用相同的执行路径。我真的认为需要对 Spring 进行改进。愿你创造一个JIRA ticket .

关于java - Spring DI 中的通用工厂方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9820966/

相关文章:

java - Realm 返回对象的空列表

java - 一对一 hibernate 映射

java - 错误: The method selectByVisibleText(string) is undefined for the type webelement

java - Hibernate SqlFragment内存泄漏?

spring - 如何在 Spring-MVC 中注册全局自定义编辑器?

spring - 在 Spring 应用程序中处理异常的位置

java - 任何 java bean 中的 spring 依赖注入(inject)

jsf - 如何在多个类实现中使用 CDI 限定符?

javascript - 协作 coffeescript 服务/类(class)

java - 凯撒密码 Java