2011-10-10 61 views
2

這可以使用轉換器的包裝來完成:春天:注入斯卡拉列表

import scala.collection.JavaConversions._ 

object ListConverter { 

    def toScalaList(jlist: java.util.List[AnyRef]) = { 
    jlist.toList 
    } 
} 

JavaConversions使用implicit def asScalaBuffer返回一個列表斯卡拉。然後,我可以榜上無名注射爲:

<bean id="someItems" class="my.package.ListConverter" factory-method="toScalaList"> 
    <constructor-arg type="java.util.List"> 
     <util:list> 
      <ref bean="itemOne"/> 
      <ref bean="itemTwo"/> 
     </util:list> 
    </constructor-arg> 
</bean> 

我想找到一個更清潔的方式來做到這一點

我真的不能使用JavaConversions直接作爲靜態工廠電話:

<bean id="someItems" class="scala.collection.JavaConversions" factory-method="asScalaBuffer">...</bean> 

由於一個implicit def是不是真的在Java宇宙的靜態方法。

P.S.爲了把它弄出來的方式。我知道有很多註解驅動的配置愛好者,但我不是其中之一,這是不是一個解決方案,我在尋找:我喜歡我的春天CONFIGS XML,和我喜歡春天到DI斯卡拉

回答

3

如果您想將java.util.List轉換爲scala List您將不得不提供自己的轉換/工廠方法,因爲不存在此類方法。

JavaConversions.asScalaBuffer可以像您在XML定義中一樣引用,因爲Scala編譯器會將實例轉換爲object實例的靜態轉發方法,除非您告訴它不要這樣做。 這裏的問題實際上實際上是這種方法返回一個scala.collection.mutable.Buffer,您仍然必須將其轉換爲List

一種替代方法是接受的Seq[A]一個實例被注入。這將作爲工作延伸Buffer[A]Seq[A] - 但你要知道,你周圍注射(可能可變)java.util.List<A>實例的包裝即可。

+0

是的,做的竅門,不知道爲什麼它以前不編譯,但後來IntelliJ Scala插件有時候會這樣做。關於使用Seq [A]而不是List [A] =>的好主意可能不是真正提倡強壯的集合類型,但就我而言,天氣並不重要,它是一個List或Seq。謝謝。 – tolitius

1

如果您ListConverter是一個object而非class,不會toScalaList被接受爲一個靜態方法?

+0

是的,這也是我嘗試過的,它確實有效。它只是不覺得乾淨,有一個包裝(ListConverter)圍繞包裝(JavaConversions)注入一個List。 – tolitius

+0

我編輯了這個問題來整合你的建議,因爲_question_確實看起來很乾淨,並且投票給你。謝謝。 – tolitius

0

你最大的問題是,在幕後,春天是天生無類型。在Spring確定目標參數/屬性的正確類型之前,您嘗試注入的列表實際上是作爲List<String>開始的。

有些的情況下,它可以這樣做,因爲相關類型保留在字節碼中(即使它在JVM上被擦除),這在注入通用方法的情況下不起作用。在其他情況下,它可以通過檢查元素來確定集合的類型。它通常得到這個權利,取決於涉及多少多態性。

當然,所有的邏輯完全是基於java.util.Collection和子類,所以Scala的集合類型,根本沒有得到入黨。

你這裏有三種解決方法:

  1. 學會愛註解驅動的注入。你不會被那種陰險的虛弱打字所咬。

  2. 創建setter方法或採用等效Java集合類型的輔助構造方法的重載。然後使用collection.JavaConverters來處理轉換。然後Spring很高興,因爲它仍然處於Java僅有的舒適區域內。

  3. (我個人最喜歡的)停止使用Spring

,保證能讓你最終會與你的轉換問題,在身邊的時候,你發現需要處理的奇偶不匹配會出現這種情況盒裝和非盒裝基元之間。