Domanda

Esiste un modo per eseguire il cast automatico dei bean Spring nella classe definita nell'XML del contesto dell'applicazione? Vorrei evitare di inserire le informazioni sul tipo dei bean in 2 punti .... nel file di configurazione xml e anche nel codice come cast.

Ad esempio, dato questo file di configurazione

<bean id="bean-name" class="SimpleSpringBean"  scope="prototype">
    <property name="myValue" value="simple value"></property>
</bean>

Posso chiamare ApplicationContext.getBean (" bean-name ") in modo da evitare di trasmettere direttamente il tipo restituito a SimpleStringBean . So di poter anche chiamare ApplicationContext.getBean (" bean-name " ;, SimpleSpringBean.class) per evitare il cast stesso, ma ho ancora le informazioni sul tipo in 2 punti.

Sembra che Spring possa ottenere le informazioni sulla classe ( ApplicationContext.getType ) o ottenere il tipo dal bean stesso, ma non c'è modo di lanciare automaticamente il tipo senza l'intervento del programmatore.

È stato utile?

Soluzione

Sono d'accordo con Sii, dovresti evitare di chiamare getBean il più possibile. Collega i tuoi fagioli a classi che dipendono da loro.

Tuttavia, se hai una singola classe che contiene il contesto dell'applicazione, puoi fornire un metodo generico wrapper come il seguente:

class MyContextHolder{
    ApplicationContext appContext;
    ......
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String beanName)
    {
        return (T)appContext.getBean(beanName);
    }
}

Quindi puoi chiamarlo senza trasmettere

MyClass mc = MyContextHolder.getBean("myClassBean");

Altri suggerimenti

La risposta è che non dovresti usare ApplicationContext.getBean () se è possibile, e sopporta quello che devi fare nel codice bootstrap. (Generalmente, non dovresti mai aver bisogno di usare getBean () al di fuori dei punti di ingresso della tua applicazione.)

Inoltre, ciò che stai chiedendo è probabilmente impossibile nel linguaggio Java. Il cast è una funzione di compilazione, combinata con un controllo di runtime. Il tipo di ritorno di getBean () deve essere semplicemente conosciuto al momento della compilazione. Anche se Spring può determinare il tipo di un oggetto, non può cambiare le proprie firme del metodo in fase di esecuzione.

Un'altra cosa è che anche se ciò fosse possibile, la funzionalità non sarebbe molto utile. Poiché Spring AOP è implementato utilizzando proxy dinamici, quasi sempre vuoi che Spring ti dia un'istanza di un'interfaccia implementata dal bean (che potrebbe essere un proxy AOP), non della classe di implementazione.

Un altro approccio che uso anche è autowiring la classe bootstrap usando:

public class Main {
    @Autowired FooFacade foo;
    @Autowired BarFacade bar;

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("appCtx.xml");
        AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
        Object main = bf.createBean(Main.class, 
                                    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT,
                                    false);
        ((Main) main).run();
    }

    private void run() {
        foo.doBootstrapStuff();
        bar.doMoreBootstrapStuff();
    }
}

(Codice fatto dalla memoria. Potrebbe funzionare solo se il contesto Spring è configurato per elaborare le annotazioni di cablaggio, in tal caso fare in modo che i setter per foo e bar funzionino. )

Il motivo principale per cui getBean è non tipizzato è la compatibilità di Spring (fino alla versione 2.5.x) con Java 1.4. La primavera 3.0 lo lascerà e quindi offrirà il metodo getBean digitato quindi

Tuttavia dovresti evitare di cercare direttamente i fagioli e minimizzarne il più possibile l'utilizzo

Che cosa succede se uso Spring come factory di oggetti che la mia applicazione utilizza ampiamente. Cioè, invece di scrivere un gruppo di classi che già ereditano o si avvolgono classi Java conosciute Decido solo di spostare tutto ciò in un file XML da tagliare righe di codice Java. Ciò significherà molte righe di xml ma non dovrò crearle classi scheletro Java che ho iniettato con Spring o autowire. Così facendo le linee di codice Java in meno.

Per questo motivo e ancora come sono nuovo in primavera, ho già affermato in precedenza i post utilizzavano metodi Java statici che avvolgono getBeans ().

Ho lavorato con Spring ma è ancora nuovo per me, quindi perdona la mia domanda.

" Poiché Spring AOP è implementato utilizzando proxy dinamici, quasi sempre vuoi che Spring ti dia un'istanza di un'interfaccia implementata dal bean (che potrebbe essere un proxy AOP), non della classe di implementazione "

Quindi non c'è modo di ottenere un proxy dinamico usando getBean (), qual è la migliore pratica se non ci sono interfacce ed è una classe di driver stand-alone da eseguire?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top