2012-09-21 12 views
22

Ho una classe Util con metodi statici. All'interno della mia classe Util, voglio usare i bean spring, quindi li ho inclusi nella mia classe util. Per quanto ne so, non è una buona pratica usare i fagioli primaverili come campi statici. Ma c'è un modo per accedere ai bean a molla in un metodo statico?Accesso ai bean a molla nel metodo statico

Il mio esempio:

public class TestUtils { 

    private static TestBean testBean; 

    public void setTestBean(TestBean testBean) { 
    TestUtils.testBean = testBean; 
    } 

    public static String getBeanDetails() { 
    return beanName = testBean.getDetails(); 
    } 
} 

ho visto in molti forum che questa non è una pratica migliore. Qualcuno può mostrarmi come posso gestire questo tipo di scenario?

mio file di configurazione:

<bean id="testUtils" class="com.test.TestUtils"> 
<property name="testBean" ref="testBean" /> 
</bean> 

risposta

0

L'approccio si è delineato è quello che ho visto di essere usato per iniettare un bean Spring in una classe di utilità.

<bean id="testUtils" class="com.test.TestUtils"> 
<property name="testBean" ref="testBean" /> 
</bean> 

Un'altra opzione è:

<bean name="methodInvokingFactoryBean" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
     <property name="staticMethod" value="TestUtils.setInstance"/> 
     <property name="arguments"> 
      <list> 
       <ref bean="testBean"/> 
      </list> 
     </property> 
</bean> 

con:

public class TestUtils { 

    private static testBean; 

    public static void setInstance(TestBean anInstance) { 
    testBean = anInstance; 
    } 

    public static String getBeanDetails() { 
    return testBean.getDetails(); 
    } 
} 

Maggiori dettagli sono here e here

+0

Non è chiaro per me .. Si può plz aggiungere la configurazione testBean? – TechSpellBound

1

Così ho iniettato da molla per un campo statico.

<bean id="..." class="..."> 
<property name="fieldToBeInjected"> 
      <util:constant static-field="CONSTANT_FIELD" /> 
     </property> 
</bean> 

Forse questo ti aiuterà anche.

10

Il risultato di metodi statici dovrebbe dipendere SOLO dai parametri passati nel metodo, pertanto non è necessario chiamare alcun bean.

Se è necessario chiamare un altro bean, il metodo deve essere un metodo membro di un bean standalone.

Altre risposte forniscono soluzioni di lavoro, ma il fatto che possa essere fatto non significa che dovrebbe essere fatto.

+0

Sì, penso che dovremmo usarlo come parametro invece di impostare direttamente nella classe statica. In base agli standard, afferma che non dovremmo usare il bean come statico, ma possiamo farlo in modi diversi, come mostrato nelle risposte precedenti. Grazie per la risposta. – Rosh

+1

"Il risultato dei metodi statici dovrebbe dipendere SOLO dai parametri passati nel metodo", bel colpo! – Nickolas

9

si può anche implementare l'interfaccia ApplicationContextAware, in questo modo:

@Component 
public class TestUtils implements ApplicationContextAware { 

    private static ApplicationContext ac; 

    public static String getBeanDetails() { 
    return beanName = ((TestBean) ac.getBean("testBean")).getDetails(); 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext ac) { 
    this.ac = ac; 
    } 

} 
29

Il mio approccio è per il bean si vuole accedere ad attuare InitializingBean o utilizzare @PostConstruct, e contenente un riferimento statico a se stessa.

Ad esempio:

@Service 
public class MyBean implements InitializingBean { 
    private static MyBean instance; 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     instance = this; 
    } 

    public static MyBean get() { 
     return instance; 
    } 
} 

utilizzo nella classe statica sarebbe quindi solo:

MyBean myBean = MyBean.get(); 

In questo modo, non è necessaria alcuna configurazione XML, non c'è bisogno di passare il fagiolo in come argomento del costruttore, e il chiamante non ha bisogno di sapere o preoccuparsi che il bean sia cablato usando Spring (cioè, non c'è bisogno di variabili disordinate ApplicationContext).

+0

slick - C'è un buon posto per trovare una soluzione alternativa corretta per tali problemi ricorrenti in primavera ..? –

1

Simile alla risposta di @ nullPainter, ma abbiamo fatto quanto segue. Nessuna logica post-costruzione richiesta.Imposta semplicemente il membro statico direttamente durante l'iniezione (nel metodo @Autowired).

@Service 
public class MyUtil { 

    private static MyManager myManager; 

    @Autowired(required = true) 
    public void setMyManager(MyManager manager) { 
     myManager = manager; 
    } 

    public static MyManager getMyManager() { 
     return myManager; 
    } 
} 
+0

Non è necessario passare il parametro 'required = true' poiché questo è il valore predefinito per' @ Autowired'. Quindi solo '@Autowired public void setMyManager (gestore MyManager) { myManager = manager; } ' sarebbe sufficiente. – rumman0786

+0

richiede l'annotazione @Service che ha poco senso – rohanagarwal

0

Questo funziona per me. In qualche classe:

import org.springframework.web.context.ContextLoader; 
import org.springframework.web.context.WebApplicationContext; 

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); 
DataSource datasource = (DataSource)context.getBean("dataSourceDB_01");  

E nella mia configurazione XML:

<bean id="dataSourceDB_01" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName"><value>${db.driver}</value></property>  
    <property name="url"><value>${db.url}</value></property> 
    <property name="username"><value>${db.username_seg}</value></property> 
    <property name="password"><value>${db.password_seg}</value></property> 
</bean> 

HTH

Problemi correlati