2012-02-29 7 views
14

Sto mantenendo un grande sistema Java EE. La maggior parte della logica aziendale viene convertita da EJB: s in POJO: s configurati in diversi file di configurazione del contesto di primavera. EJB: s sono principalmente utilizzati come facciate, che cercano i bean di primavera della logica aziendale da un contesto composto da tutti i file di configurazione del contesto di primavera menzionati in precedenza. Per questo usiamo il AbstractStatelessSessionBean fornito con la struttura di primavera.Override default-lazy-init = true per le definizioni dei bean Spring

Tutti questi file di configurazione hanno la direttiva default-lazy-init = true, il che significa che i bean di business logic non vengono creati finché non vengono effettivamente utilizzati dal sistema. Questo è preferibile la maggior parte del tempo poiché la ripubblicazione in modalità sviluppatore diventa più veloce.

Tuttavia, quando vengono effettuate fusioni di grandi dimensioni, si riscontrano problemi nel trovare tutti gli errori di configurazione, come le dipendenze mancanti.

La mia idea è di scrivere qualche forma di test di integrazione, con lo scopo di trovare quegli errori. Ciò significa, penso, che ho bisogno di trovare un modo per sovrascrivere tutte le dichiarazioni default-lazy-init = true durante la creazione del contesto dell'applicazione.

C'è un modo per farlo a livello di programmazione, o forse con un file di contesto di solo test che include tutti i file di contesto attuali?

+0

Volevo solo menzionare che i bean EJB3 sono tanto POJO quanto 'POJO: s configurati in diversi file di configurazione del contesto di primavera'. –

+0

Ok, per il momento siamo bloccati con EJB 2.x. Probabilmente ci trasferiremo su EJB 3 in futuro. – Jon

+0

Mi spiace sentirlo. EJB 2 è un dispositivo inventato per torturare gli sviluppatori :(Spero che sarai in grado di passare presto all'EJB 3 (è dal 2006, quindi non è poi così nuovo) –

risposta

14

Diciamo attualmente si dispone di un singolo applicationContext.xml file contenente tutte le definizioni di fagioli:

<beans default-lazy-init="true"> 

    <!-- all your beans --> 

</beans> 

rinominarlo in applicationContext-main.xml o qualcosa e rimuovere l'attributo default-lazy-init="true". Ora creare due file: applicationContext.xml

<beans default-lazy-init="true"> 

    <import resource="applicationContext-core.xml"/> 

</beans> 

e:

<beans default-lazy-init="false"> 

    <import resource="applicationContext-core.xml"/> 

</beans> 

Come si può vedere l'unica differenza è il valore di default-lazy-init. Durante lo sviluppo, il team può utilizzare la versione precedente di applicationContext.xml che include tutti i bean con lazy-init. Negli ambienti di staging e testing passare a quest'ultimo in modo che tutti i bean inclusi in applicationContext-core.xml vengano creati con entusiasmo.

+0

Grazie per la risposta rapida. I nostri file di configurazione hanno una struttura piuttosto complessa di comprende, vedrò cosa posso fare di questo. – Jon

+0

avete mai provare questo? ' 'impossibile eseguire i bean con entusiasmo. – pootow

+2

Per la mia versione di Spring, 3.1.2, l'impostazione default-lazy-init nell'elemento di livello superiore dei bean non si applica ai bean all'interno di una risorsa importata.In questo sono d'accordo con pootow. Chissà se funziona con una versione diversa della primavera, sarebbe bello. Quello che dovevo fare era come ha detto Jon. – DanielKWinsor

7

Credo che il modo migliore per controllare lazy init di bean sia lasciare il default-lazy-init da tutti i file di configurazione eccetto quello più in alto come suggerisce Tomasz Nurkiewicz. In questo caso, tuttavia, ho avuto bisogno di una soluzione rapida e sporca per verificare tutte le definizioni dei bean. (E 'un po' di un processo di cambiare la politica di init pigro.)

mi si avvicinò con un semplice BeanFactoryPostProcessor che sembra fare il lavoro:

public class NonLazyInitBeanFactoryPostProcessor implements BeanFactoryPostProcessor { 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
     for (String beanName : beanFactory.getBeanDefinitionNames()) { 
      beanFactory.getBeanDefinition(beanName).setLazyInit(false); 
     } 
    } 
} 

Se inserite in un file di contesto, lo farà sovrascrivere il flag pigro di init impostato da qualsiasi file di contesto incluso.

<beans default-lazy-init="false"> 
    <bean class="example.NonLazyInitBeanFactoryPostProcessor" /> 
    <import resource="applicationContext-core.xml"/> 
</beans> 

Se cerco di creare un contesto dal XML qui sopra, errori di configurazione precedentemente nascoste da inizializzazione pigra mostrerà immediatamente come eccezioni.

1

C'è un 'ma' in questo PostProcessor

for (String beanName : beanFactory.getBeanDefinitionNames()) { 
     beanFactory.getBeanDefinition(beanName).setLazyInit(false); 
    } 

Questo ciclo for si iterare solo su top maggior parte dei fagioli non compreso e.g definizioni del bean interno (locale) ...

0

Non è possibile accedere allo scanner dal contesto: è completamente privato, ma dal momento che è possibile accedere al codice sorgente, è possibile visualizzare ciò che è necessario impostare personalmente. Ho usato proprio ReflectionTestUtils di primavera per impostare il mio scanner configurato nel contesto:

ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); 
    BeanDefinitionDefaults defaults = new BeanDefinitionDefaults(); 
    defaults.setLazyInit(true); 
    scanner.setBeanDefinitionDefaults(defaults); 
    ReflectionTestUtils.setField(context, "scanner", scanner); 
    context.scan("com.some.path"); 

È possibile farlo ovunque ci sia accesso al contesto di applicazione prima della scansione dei componenti avviene.

Problemi correlati