2013-06-08 12 views
11

Sono nuovo in Primavera.Come passare i parametri dinamicamente ai bean Spring

Questo è il codice per la registrazione di fagioli:

<bean id="user" class="User_Imple"> </bean> 
<bean id="userdeff" class="User"> </bean> 

e questo è il mio classe bean:

public class User_Imple implements Master_interface { 

    private int id; 
    private User user; // here user is another class 

    public User_Imple() { 
     super(); 
    } 

    public User_Imple(int id, User user) { 
     super(); 
     this.id = id; 
     this.user = user; 
    } 

    // some extra functions here.... 
} 

e questo è il mio metodo principale per eseguire l'azione:

public static void main(String arg[]) { 

    ApplicationContext context = new ClassPathXmlApplicationContext("/bean.xml"); 
    Master_interface master = (Master_interface)context.getBean("user"); 

    // here is my some operations.. 
    int id = ... 
    User user = ... 

    // here is where i want to get a Spring bean 
    User_Imple userImpl; //want Spring-managed bean created with above params 
} 

Ora voglio chiamare questo costruttore con parametri, e questi parametri sono generati dinamicamente nel mio metho principale ds. Questo è ciò che intendo per passare dinamicamente - non staticamente, come dichiarato nel mio file bean.config.

risposta

2

Si prega di dare un'occhiata a Constructor injection.

Inoltre, dai un'occhiata a IntializingBean e BeanPostProcessor per altre intercettazioni del ciclo di vita di un springbean.

+2

Potete per favore citare riferimenti per il motivo per cui 'iniezione setter' è preferibile rispetto costruttore –

+0

"La squadra Primavera sostiene generalmente costruttore iniezione in quanto consente di implementare i componenti dell'applicazione come oggetti immutabili e di garantire che le dipendenze richieste non siano nulle ... L'iniezione di setter deve essere utilizzata principalmente solo per dipendenze opzionali che possono essere assegnate a valori di default ragionevoli all'interno della classe "- http: // docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html –

+1

Penso che "dinamicamente" l'utente volesse dire passare gli argomenti nel main me Thod, o generalmente al momento di ottenere il fagiolo. chiamare getBean (...) e passare argomenti direttamente funziona, ma spostare questa chiamata a un localizzatore (modello di Service Locator) potrebbe essere fatto per evitare la dipendenza da Spring Framework nel codice. Il localizzatore può essere passato come bean e il localizzatore ApplicationContextAware può chiamare getBean (bean, arg1, arg2 ...). L'ambito del bean dovrebbe essere "prototipo". vedi anche: http://stackoverflow.com/questions/812415/why-is-springs-applicationcontext-getbean-considered-bad –

0

Forse lasciare che il User_Imple sia un Pojo ordinario (anziché un fagiolo di primavera) risolverà il tuo problema?

<!-- Only use User as a Spring Bean --> 
<bean id="userdeff" class="User"></bean> 

Java:

public static void main(String arg[]) 
{ 
    ApplicationContext context =new ClassPathXmlApplicationContext("/bean.xml"); 
    User user = context.getBean(User.class); 

    int id = // dynamic id 
    Master_interface master = new User_Imple(id, user); 
} 
+0

ya è buono @matsev, se ho meno no. di classe usiamo direttamente i POJO ma in MVC nascondiamo completamente il file di business .. quindi passiamo attraverso i bean .. –

+0

Quindi hai bisogno di una classe di fabbrica a cui puoi fare riferimento da Spring. Spring usa (più o meno) solo Singletons – cljk

1

iniezione Constructor può aiutare. In questo caso potrebbe essere necessario generare un POJO con ID e utente come attributi e passare POJO al costruttore. Nell'iniezione del costruttore nel file di configurazione è possibile fare riferimento a questo costruttore con pojo come riferimento. Quindi gestirai il valore dinamico dei dati in ID e Utente.

Spero che questo aiuti !!

18

Se ho capito bene, la risposta corretta è usare #getBean (String beanName, Object ... args) che passerà gli argomenti al bean. Posso mostrarti come è fatto per la configurazione basata su java, ma dovrai scoprire come è fatto per la configurazione basata su xml.

@Configuration 
public class ApplicationConfiguration { 

    @Bean 
    @Scope("prototype") //As we want to create several beans with different args, right? 
    String hello(String name) { 
    return "Hello, " + name; 
    } 
} 

//and later in your application 

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfiguration.class); 
String helloCat = (String) context.getBean("hello", "Cat"); 
String helloDog = (String) context.getBean("hello", "Dog"); 

È questo che stai cercando?

Aggiornamento. Questa risposta ottiene troppe revisioni e nessuno guarda il mio commento. Anche se è una soluzione al problema, è considerato come anti-pattern di primavera e non dovresti usarlo! Ci sono molti modi diversi di fare le cose per bene utilizzando fabbrica, ricerca-metodo, ecc ..

Utilizzare il seguente SO inserire come punto di riferimento: create beans at runtime

+3

Si prega di essere consapevoli che non è la soluzione migliore quando si utilizza "DI", perché in realtà qui abbiamo un "localizzatore di servizio" (che è opposto a DI). Di solito, quando hai incontrato troppi context.getBean significa che qualcosa viene fatto in un modo sbagliato. –

1

penso che le soluzioni proposte in precedenza per utilizzare l'iniezione costruttore/setter injection non funziona perfettamente per il caso d'uso che stai cercando. Spring assume più o meno valori di argomento statici per costruttori/setter. Non vedo un modo per passare dinamicamente i valori per ottenere un bean da Spring Container. Tuttavia, se si desidera ottenere le istanze di User_Imple dinamicamente, mi consiglia di utilizzare una classe factory User_Imple_Factory


    public class User_Imple_factory { 
     private static ApplicationContext context =new ClassPathXmlApplicationContext("/bean.xml"); 

     public User_Imple createUserImple(int id) { 
      User user = context.getBean("User"); 
      return new User_Imple(id, user); 
     } 
    } 
 
+0

implementare ApplicationContextAware per evitare la creazione di un nuovo ApplicationContext che potrebbe essere creato da qualche altra parte. –

Problemi correlati