我想知道为什么在 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 对象
涉及的逻辑在ConstructorArgumentValues中getArgumentValue
方法以及 getIndexedArgumentValue
和 getGenericArgumentValue
方法中的持有者。这两种方法都使用测试根据可用信息拒绝 ValueHolder
。
在第二个配置场景中,使用索引检测并拒绝值,因为所需类型 String
与 Object
不完全匹配。此测试使用 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/