I want to be able to create a Tuple2
from spring config where I explicitly declare the types of my parameters:
<bean class="scala.Tuple2">
<constructor-arg index="0" value="Europe/London" type="java.util.TimeZone" />
<constructor-arg index="1" value="America/New_York" type="java.util.TimeZone" />
</bean>
This does not work (I have the relevant property editors specified in my config file). At runtime I 开发者_JAVA百科get the error:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'scala.Tuple2#6504bc' defined in file [C:\Work\myproj\config\test\myproj.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.Object]: Ambiguous constructor argument types - did you specify the correct bean references as constructor arguments?
The error goes away if I do not declare the explicit type
- but then of course the Tuple2
in my program is just a (String, String)
which is not what I want.
EDIT for those of you who did not know this, Spring uses PropertyEditor
s to create instances from Strings as follows:
public class TimeZoneEditor extends java.beans.PropertyEditorSupport {
public void setAsText(String text) { setValue(TimeZone.getTimeZone(text)); }
public String getAsText() { return ((TimeZone)getValue()).getID(); }
}
Now I simply declare in my config:
<bean id="customEditorConfigurer"
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.TimeZone">
<bean class="my.cleve.rutil.TimeZoneEditor"/>
</entry>
</map>
</property>
</bean>
And hey presto I can do things like:
<map key-type="java.util.TimeZone" value-type="java.lang.Integer">
<entry key="Europe/London" value="4" />
</map>
Or alternatively Spring can figure out the generic type parameters from your setter methods. Except it doesn't seem to work in the case of my Tuple2
!
You will need to create the TimeZone parameters explicitly using the static method getTimeZone() of class TimeZone:
<bean class="scala.Tuple2">
<constructor-arg index="0">
<bean class="java.util.TimeZone" factory-method="getTimeZone">
<constructor-arg value="Europe/London"/>
</bean>
</constructor-arg>
<constructor-arg index="1">
<bean class="java.util.TimeZone" factory-method="getTimeZone">
<constructor-arg value="America/New_York"/>
</bean>
</constructor-arg>
</bean>
It may be working for Map because spring has special support for it through the syntax you specified:
<map key-type="java.util.TimeZone" value-type="java.lang.Integer">
In this case, spring probably determines it should invoked the property editors based on the mismatch between the provided values of type String
and the requested types TimeZone
and Integer
.
精彩评论