2012-05-15 11 views
7

Diciamo che ho una classe con un costruttore che accetta uno o più argomenti. Diciamo anche che gli argomenti dovrebbero essere un tipo di input da parte dell'utente. L'argomento non può essere conosciuto in fase di compilazione o di configurazione, solo in fase di esecuzione. Dovrei definire la mia classe come un prototipo di fagiolo primaverile o dovrei semplicemente crearlo con "nuovo".Costruttore che accetta argomenti - Definisci come oggetto ordinario o bean a molla?

Se dovessi definirlo come bean, come posso passare gli argomenti?

risposta

7

Questo è problematico in primavera. Se la tua classe non ha dipendenze da altri bean, creala con new. Se hai una classe che dipende da altri bean Spring ma vuoi comunque passare alcuni argomenti di runtime, attualmente Spring non la supporta.

Tuttavia dare un'occhiata a SPR-7431 e my article about passing custom argument to <lookup-methods/>. Se tutto va bene, questa funzione dovrebbe far parte di Spring 3.2 e dovrebbe corrispondere alle tue esigenze. Fondamentalmente consente di creare prototype fagioli -scoped mentre passa ancora qualche argomento del costruttore.

+0

Informazioni molto buone e piacevoli. Grazie Aggiornamento –

+0

: questa funzione NON fa ancora parte della primavera. – javadeveloper

+0

è supportato nella primavera 4 ora? –

5

A meno che la tua classe non abbia dipendenze da altri bean nel tuo contesto, allora no, non dovresti renderlo un bean - non ha senso. Basta usare new.

L'unico motivo valido per renderlo un bean è se fa dipende da altri bean, nel qual caso è giustificato un bean con ambito prototipo. Tuttavia, se la classe richiede quei valori di runtime nel suo costruttore, non è possibile farlo realmente, a meno di cambiare la classe per iniettarli tramite un metodo invece di usare il costruttore.

+0

Beh .. l'oggetto che voglio creare è in realtà dovrebbe tornare Fagioli primavera in uno dei suoi metodi in modo che _does_ dipende da loro. Ma se non può essere fatto, allora non può essere fatto ... –

+0

@LudwigMagnusson: Suggerisco di refactoring della classe, quindi, in modo che i valori di runtime siano passati al metodo che restituisce il bean appropriato, piuttosto che passarli nel costruttore. – skaffman

+0

Questo non è possibile. La classe implementa un'interfaccia che definisce il metodo e non può accettare argomenti poiché le classi di implementazione dovrebbero essere in grado di creare i bean da diversi tipi di input. Ma forse se penso più a fondo su questo, posso rifattenerlo in questo modo ... –

0

primavera-caratteristica di argomenti passa al costruttore usando il lavoro di ricerca metodo doesnt in primavera 3.2.11, ma funziona nella versione 4.1.1 primavera

qui il codice che ho usato per controllarlo:

questa è la fabbrica di interfaccia ...

package prueba; 

public interface Factory { 

    Person createPersonWithDependencies(String name); 
} 

questo è il fagiolo che vogliamo essere gestito entro la primavera, iniettando HelloWorldService ...

package prueba; 

public class Person { 

    private HelloWorldService helloWorldService; 

    public final void setHelloWorldService(HelloWorldService extraService) { 
     this.helloWorldService = extraService; 
    } 

    public Person() { 
     super(); 
    } 

    public Person(String name) { 
     super(); 
     this.name = name; 
    } 

    private String name; 

    public final String sayHello() { 
     return helloWorldService.getGreeting()+" I am "+name; 
    } 
} 

questo è il famoso servizio helloworld:

package prueba; 

public class HelloWorldService { 

    public String getGreeting(){ 
     return "hello world"; 
    } 
} 

questo è un servizio esempio che utilizza la Fabbrica

package prueba; 

public class Service { 

    private Factory factory; 

    public final void setFactory(Factory factory) { 
     this.factory = factory; 
    } 


    public void doSomeThing(){ 
     Person bean1= factory.createPersonWithDependencies("Jhon"); 

     System.out.println(bean1.sayHello()); 

     Person bean2= factory.createPersonWithDependencies("Maria"); 

     System.out.println(bean2.sayHello()); 
     System.out.println(bean1.sayHello()); 

    } 
} 

questa è la classe principale che mette alla prova tutti

package prueba; 

import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class TestLookupMethodWithArguments { 
    /** 
    * Main method. 
    */ 
    public static void main(String[] args) { 

     ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml"); 

     Service service=applicationContext.getBean("service",Service.class); 

     service.doSomeThing(); 
    } 

} 

e, infine, il file di configurazione di primavera:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 

    <bean id="helloWorldService" class="prueba.HelloWorldService" /> 

    <bean id="Person" class="prueba.Person" scope="prototype"> 
     <property name="helloWorldService" ref="helloWorldService" /> 
    </bean> 

    <bean id="myFactory" class="prueba.Factory"> 
     <lookup-method name="createPersonWithDependencies" bean="Person" /> 
    </bean> 

    <bean id="service" class="prueba.Service"> 
     <property name="factory" ref="myFactory" /> 
    </bean> 
</beans> 

l'output utilizzando primavera 4.1.1

hello world I am Jhon 
hello world I am Maria 
hello world I am Jhon 
Problemi correlati