2012-03-22 23 views
6

mi chiedo perché in primavera DI funziona la seguente definizione di fagioli (io uso bean instantiation with a static factory method e Guava di Suppliers.ofInstance):metodo generico fabbrica in primavera DI

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

ma questo non lo fa:

<bean id="keySupplier" class="com.google.common.base.Suppliers" 
    factory-method="ofInstance"> 
    <constructor-arg type="java.lang.String" value="someReallyLongValue" /> 
</bean> 

Viene generata la seguente eccezione:

org.springframework.beans.factory.BeanCreationException: Errore di creazione g di fagioli con nome 'userRepo' definito nella risorsa percorso della classe:
(...)
dipendenza Insoddisfatto esprime attraverso argomento del costruttore con indice 0 di tipo [java.lang.Object]:
tipi metodo factory di argomenti ambigui - ha fatto si specificano i riferimenti bean corretti come argomenti del metodo factory?

Il problema è, nel mio caso, quando uso la definizione prima di fagioli con davvero lunga stringa come un valore mia linea dell'editor pause dopo l'ultimo carattere della stringa, che causa che stringa viene passata con l'aggiunta di spazi-Suppliers.ofInstance e di conseguenza rompe il mio codice.

La seconda definizione sarebbe più rigida per gli spazi bianchi ma, sorprendentemente, non funziona (probabilmente non affronta il tipo generico, nonostante il tipo sia specificato nell'attributo type).

Posso forzare Spring a ignorare lo spazio vuoto nel tag <value> in qualche modo?

Oppure utilizzare correttamente <constructor-arg type="java.lang.String" value="someReallyLongValue" />? O dovrei presentare un problema perché si tratta di un bug di primavera?

Preferisco non fare alcuna ipotesi sulla stringa (ad esempio, utilizzare string.trim() qui).

+0

Prima di tutto, configurare l'editor XML in modo che non si inseriscano interruzioni di riga automaticamente. Se non esiste tale opzione, cambia editor;) –

+0

@ YvesMartin Posso configurare il mio editor per farlo, ma se qualcun altro in futuro esegue la formattazione (semplice 'CSf' in Eclipse), non mi piace il fatto che l'applicazione sarà rotto a causa di ciò. – Xaerxess

+1

Tale problema esisterà sempre. È necessario spostare tali informazioni di testo nel file delle proprietà. –

risposta

0

mi sento di raccomandare di utilizzare un file di proprietà e quindi utilizzare la proprietà nella definizione

Ma questo non spiega il vostro comportamento osservato.

+0

In realtà ho scelto 'Fornitore ' non 'String' come dipendenza perché avrò intenzione di fare cose più avanzate con il fornitore (valore memoize fornito, ottenere String dal file registro/proprietà ecc.). Questo caso concreto è una specie di implementazione simulata del bean 'keySupplier' ed è per questo che ho usato la fabbrica statica' Suppliers.ofInstance' qui e perché sono curioso del fallimento della creazione del bean. – Xaerxess

0

Non sicuro al 100%, ma cercare

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

Non sono sicuro che il codice sia ma l'ordine che si posiziona l'args costruttore non è considerata se non si specifica la posizione. Se hai più costruttori, questo può rovinare tutto.

+0

No, questo non aiuta qui - ha ottenuto la stessa eccezione. BTW intendevi '', giusto? – Xaerxess

6

Le due configurazioni non implicano lo stesso percorso di esecuzione in primavera in base a reference documentation about constructor resolution. L'errore deriva dai generici utilizzati per this instanceOf method che dichiara come argomento del metodo Object.

primavera ha a che fare le seguenti operazioni per avere successo:

  • trovare il metodo giusto in base alle argomentazioni
  • valori letterali
  • convertire XML in oggetti Java sia grazie alla esplicita type dichiarazione o in base ai tipi metodo argomento quando index viene utilizzato

la logica è coinvolta in ConstructorArgumentValues supporto nel metodo getArgumentValue e in entrambi getIndexedArgumentValue un d getGenericArgumentValue. Entrambi i metodi utilizzano i test per rifiutare uno ValueHolder in base alle informazioni disponibili.

Nel secondo scenario di configurazione, viene utilizzato il rilevamento indicizzato e rifiuta il valore poiché il tipo richiesto String non corrisponde esattamente a Object. Questo test viene eseguito con ClassUtils.matchesTypeName che non controlla la gerarchia dei tipi.

Nel primo scenario di configurazione, il valore titolare è pronto con un oggetto String e il meccanismo di argomento generico accetta perché il valore è assegnabile al tipo di argomento del metodo rilevato.

In teoria, la seguente espressione dovrebbe funzionare perché viene fornito il tipo per generare l'oggetto dal valore e l'indice viene fornito per evitare qualsiasi ipotesi, anche se esiste un solo metodo di corrispondenza.

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

Sfortuna, non migliora nulla, lo stesso percorso di esecuzione è ancora utilizzato. Penso davvero che sia necessario un miglioramento di primavera. Si può creare un JIRA ticket.

+1

La differenza tra '' e '' documentata da qualche parte o hai controllato il codice sorgente? – Xaerxess

+1

Ho creato [un ticket] (https://jira.springsource.org/browse/SPR-9270), ora aspetterò se il bug è confermato. – Xaerxess

+0

Non lo considero un bug ma un miglioramento. A proposito, il modulo consigliato per fare questa configurazione è l'uso del tag ""! –