Общий фабричный метод в Spring DI - PullRequest
6 голосов
/ 22 марта 2012

Интересно, почему в Spring DI работает следующее определение бина (я использую создание экземпляра бина со статическим фабричным методом и Guava's 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: Ошибка создания компонента с именем 'userRepo', определенным в ресурсе пути к классу:
(...)
Неудовлетворенная зависимость выражается через аргумент конструктора с индексом 0 типа [java.lang.Object]:
Неоднозначные типы аргументов метода фабрики - вы указали правильные ссылки на bean-компоненты как аргументы метода фабрики?

Проблема, в моем случае, когда я использую определение первого компонента с действительно длинной строкой в ​​качестве значения, мой редактор разбивает строку после последнего символа строки, что приводит к тому, что строка передается с дополнительным пробелом для Suppliers.ofInstance и в результате это нарушает мой код.

Второе определение будет более строгим в отношении пробелов, но, к удивлению, оно не работает (вероятно, оно не справляется с универсальным типом, несмотря на то, что тип указан в атрибуте типа).

Могу ли я заставить Spring игнорировать пробелы в теге <value>?

Или я правильно использую <constructor-arg type="java.lang.String" value="someReallyLongValue" />? Или я должен сообщить о проблеме, потому что это ошибка Spring?

Я бы предпочел не делать никаких предположений относительно строки (т. Е. Использовать string.trim() здесь).

Ответы [ 3 ]

6 голосов
/ 27 марта 2012

Две конфигурации не включают в себя один и тот же путь выполнения в Spring в соответствии с справочной документацией о разрешении конструктора .Отказ происходит из-за обобщений, используемых для этого метода instanceOf , который объявляет Object в качестве аргумента метода.

Spring должен выполнить следующие задачи для успеха:

  • найти правильный метод в соответствии с аргументами
  • конвертировать литеральные значения XML в объекты Java либо благодаря явному объявлению type, либо на основе типов аргументов метода при использовании index

Используемая логика находится в ConstructorArgumentValues ​​ держателе в методе getArgumentValue и в getIndexedArgumentValue и getGenericArgumentValue.Оба метода используют тесты для отклонения ValueHolder на основе доступной информации.

Во втором сценарии конфигурации используется индексированное обнаружение, и оно отклоняет значение, поскольку требуемый тип String не точно совпадает с Object.Этот тест выполняется с ClassUtils.matchesTypeName, который не проверяет иерархию типов.

В первом сценарии конфигурации держатель значения готов с объектом String и механизмом общего аргументасоглашается, потому что значение присваивается обнаруженному типу аргумента метода.

Теоретически, следующее выражение должно работать, потому что тип предоставляется для генерации объекта из значения, а индекс предоставляется, чтобы избежать каких-либо догадок, даже если существуетсоответствует только один метод.

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

Не повезло, ничего не улучшается, тот же путь выполнения все еще используется.Я действительно думаю, что требуется улучшение Spring.Можете ли вы создать JIRA билет .

0 голосов
/ 23 марта 2012

Не уверен на 100%, но попробуйте

  <value index="0" [...]

Не уверен, как выглядит ваш код, но порядок размещения аргументов конструктора не учитывается, если не указать местоположение.Если у вас несколько конструкторов, это может испортить ситуацию.

0 голосов
/ 22 марта 2012

Я бы рекомендовал использовать файл свойств, а затем использовать свойство в определении

Но это не объясняет вашего наблюдаемого поведения.

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