2011-01-20 12 views
5

Ho una domanda relativa a possibili problemi di prestazioni durante l'utilizzo dell'annotazione @EJB. Immaginate il seguente scenario@EJB injection vs lookup - performance issue

public class MyBean1 implements MyBean1Remote{ 
@EJB 
private MyBean2Remote myBean2; 
@EJB 
private MyBean2Remote myBean3; 
... 
@EJB 
private MyBean20Remote myBean20; 
} 

C'è un bean con molte dipendenze rispetto agli altri bean. In base alle specifiche EJB se mi piacerebbe iniettare MyBean1Remote su un altro bean, il contenitore dovrebbe prendere tutte le dipendenze richieste dal suo pool per iniettarlo in MyBean1Remote e quindi inserire il riferimento allo stub MyBean1Remote.

così nel seguire le esigenze del contenitore scenario riservati 20 EJB (myBean1 e le sue dipendenze 19)

public class MyAnotherBean implement MyAnotherRemote{ 
    @EJB 
    private MyBean1Remote myBean1 
} 

diciamo che nella maggior parte dei casi useremo solo dipendenza da un unico per ogni formula commerciale di myBean1. Di conseguenza, ogni volta che vogliamo iniettare quel bean, forziamo il contenitore a riservare molti EJB non necessari. Supponiamo anche che stiamo operando su bean remoti, quindi probabilmente il contenitore dovrebbe anche eseguire alcuni algoritmi di bilanciamento del carico prima di iniettare i bean dipendenti.

Domande:

  1. Non sarebbe causa prenotazione delle risorse inutili e più oltre problema di prestazioni, mentre operano in ambiente cluster?

  2. Forse il buon vecchio ServiceLocator potrebbe essere la soluzione migliore perché con questo approccio chiederei un EJB specifico quando ne abbiamo davvero bisogno?

risposta

5

Nella maggior parte dei casi e in particolare quando si utilizzano bean di sessione stateless, le istanze bean verranno raccolte. Uno dei motivi dietro il pooling è che le ricerche di dipendenze per l'iniezione potrebbero essere relativamente costose, quindi il bean viene raggruppato con (stub per) tutte le sue dipendenze già iniettate.

Così ogni volta che si chiama un metodo su MyAnotherBean, questo bean con le sue 20 dipendenze transitive non viene creato con tutte quelle dipendenze risolte al volo. Invece, un'istanza completamente istanziata viene selezionata dal pool e la chiamata al metodo viene diretta a tale.

Si noti inoltre che, a meno che non si stia eseguendo la federazione JNDI, di solito non si possono iniettare facilmente EJB remoti.

12

Il contenitore non inserisce un'istanza dell'EJB; inietta un'istanza di un oggetto proxy leggero generato dal contenitore che implementa l'interfaccia desiderata.

public class MyBean1 implements MyBean1Remote { 
    ... 
} 

public class MyAnotherBean implement MyAnotherRemote { 
    @EJB 
    private MyBean1Remote myBean1; 
} 

Nel tuo esempio, MyAnotherBean.myBean1 sarà iniettato con un oggetto proxy che implementa l'interfaccia MyBean1Remote.

Assumendo una stateless fagioli sessione (dal momento che si parla pooling), il contenitore non allocare un caso reale EJB dal pool pronto per i metodi fino a quando un metodo viene chiamato sul proxy, e l'istanza viene restituita al pool prima che la chiamata al metodo proxy ritorni.

+0

+1 Sì, questa è anche una buona risposta :) L'istanza stessa non viene mai iniettata, ma è un proxy. Accanto a questo, come nella mia risposta, le istanze effettive nel pool hanno già risolto tutte le loro dipendenze. –