Весна: добавление списка Scala - PullRequest
2 голосов
/ 10 октября 2011

Это можно сделать с помощью конвертера:

import scala.collection.JavaConversions._

object ListConverter {

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

, который использует implicit def asScalaBuffer в JavaConversions для возврата списка Scala.Тогда я могу сделать список инъекционным:

<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.

PS Чтобы убрать его с пути.Я знаю, что есть много любителей конфигурации, управляемых аннотациями, но я не один из них, и это не решение, которое я ищу: Мне нравятся мои XML для конфигураций Spring и Мне нравится весна в DI Scala

Ответы [ 3 ]

3 голосов
/ 10 октября 2011

Если вы хотите преобразовать java.util.List в scala List, вам придется предоставить свой собственный метод преобразования / фабрики, так как такого метода не существует.

На

JavaConversions.asScalaBuffer можно ссылаться точно так же, как вы делали это в своем определении XML, так как компилятор Scala генерирует статические методы пересылки для экземпляра object, если только вы не запретите это делать. Проблема здесь на самом деле в том, что этот метод возвращает scala.collection.mutable.Buffer, который вам все еще нужно преобразовать в List.

Альтернативой является принятие экземпляра Seq[A] для инъекции. Это будет работать как Buffer[A] extends Seq[A] - но вы должны знать, что вы вводите оболочку вокруг (возможно изменяемого) экземпляра java.util.List<A> тогда.

1 голос
/ 10 октября 2011

Если ваш ListConverter был object, а не class, разве toScalaList не будет принят как статический метод?

0 голосов
/ 11 октября 2011

Ваша самая большая проблема в том, что за кулисами Spring нетипизирован. Этот список, который вы пытаетесь добавить, на самом деле начинается как List<String>, прежде чем Spring определит правильный тип целевого параметра / свойства.

В некоторых случаях это может быть сделано, потому что соответствующий тип сохраняется в байт-коде (даже если он стирается в JVM), это не будет работать в случае внедрения в универсальные методы. В других случаях он может определить тип коллекции путем проверки элементов. обычно понимает это правильно, в зависимости от степени вовлеченности полиморфизма.

Конечно, вся эта логика полностью основана на java.util.Collection и подклассах, поэтому типы коллекций Scala просто не могут присоединиться к партии.

У вас есть три решения:

  1. Научитесь любить инъекции, основанные на аннотациях. Вы не будете укушены коварным слабым набором текста.

  2. Создать перегрузку метода сеттера или вспомогательного конструктора, который принимает эквивалентные типы коллекций Java. Затем используйте collection.JavaConverters для обработки преобразования. Тогда Spring счастлив, потому что он все еще находится в комфортной зоне только для Java.

  3. (мой личный фаворит) Хватит использовать Spring

Вы гарантированно столкнетесь с проблемами с вашим конвертером, это произойдет примерно в то время, когда вы обнаружите необходимость справиться с несоответствием четности между коробочными и нераспакованными примитивами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...