In realtà, direi che l'ascolto di JMS è probabilmente la migliore ragione per un server delle applicazioni. Un broker di messaggi autonomo non risolve il problema poiché è ancora necessario un componente in ascolto per i messaggi. Il modo migliore per farlo è utilizzare un MDB. In teoria puoi usare Springs MessageListenerContainer. Tuttavia questo ha diversi svantaggi come JMS supporta solo il blocco delle letture e Spring quindi ha bisogno di far ruotare i propri thread che non è completamente supportato (anche in Tomcat) e può rompere transazioni, sicurezza, naming (JNDI) e caricamento della classe (che a sua volta può rompersi remoting). Un adattatore di risorse JCA è libero di fare tutto ciò che desidera, tra cui la rotazione di thread tramite WorkManager. Probabilmente viene utilizzato un database oltre a JMS (o un'altra destinazione), a quel punto sono necessarie le transazioni XA e JTA, in altre parole un server applicazioni. Sì, puoi applicare una patch a questo in un contenitore servlet, ma questo punto diventa indistinguibile da un server delle applicazioni.
IMHO la ragione principale contro i server delle applicazioni è che ci vogliono anni dopo che una specifica è stata pubblicata (che a sua volta richiede anni) fino a quando severs implementa le specifiche e ha eliminato i bug peggiori. Solo ora, proprio prima che EE 7 stia per essere pubblicato, abbiamo i server EE 6 che iniziano ad apparire che non sono totalmente pieni di bug. Diventa comico al punto che alcuni fornitori non correggono più bug nella loro linea EE 6 perché sono già occupati con la linea EE 7 in arrivo.
Modifica
lunga spiegazione dell'ultimo paragrafo:
Java EE in un sacco di posti si basa su ciò che è chiamato informazioni contestuali. Informazioni che non sono passate esplicitamente come argomento dal server/contenitore all'applicazione ma implicitamente "lì". Ad esempio l'utente corrente per i controlli di sicurezza. La transazione o la connessione corrente. L'attuale applicazione per cercare classi per caricare pigramente codice o deserializzare oggetti. Oppure il componente corrente (servlet, EJB, ...) per effettuare le ricerche JNDI. Tutte queste informazioni si trovano nei locali dei thread che il server/contenitore imposta prima di chiamare un componente (servlet, EJB, ...). Se si creano i propri thread, il server/contenitore non li conosce e tutte le funzionalità basate su queste informazioni non funzionano più. Potresti farla franca semplicemente non usando nessuna di queste caratteristiche nei thread che hai generato.
Alcuni link
http://www.oracle.com/technetwork/java/restrictions-142267.html#threads http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html#spring-4
Se controlliamo le specifiche Servlet 3.0 troviamo:
2.3.3.3 elaborazione asincrona
Java Enterprise Edition presenta come Sezione 15.2 .2, "Ambiente dell'applicazione Web" a pagina 15-174 e Sezione 15.3.1, "Propagazione di Secu Identità di rità nelle chiamate EJBTM "a pagina 15-176 sono disponibili solo per i thread che eseguono la richiesta iniziale o quando la richiesta viene inviata al contenitore tramite il metodo AsyncContext.dispatch. Le funzionalità di Java Enterprise Edition potrebbero essere disponibili per altri thread che operano direttamente sull'oggetto di risposta tramite il metodo AsyncContext.start (Runnable).
Riguarda l'elaborazione asincrona, ma le stesse restrizioni si applicano ai thread personalizzati.
public void start (Runnable r) - Questo metodo consente al contenitore di inviare un thread, possibilmente da un pool di thread gestito, per eseguire il Runnable specificato. Il contenitore può propagare informazioni contestuali appropriate al Runnable.
Ancora, elaborazione asincrona ma le stesse restrizioni si applicano ai thread personalizzati.
15.2.2 Web Application Environment
Questo tipo di contenitore di servlet dovrebbe sostenere questo comportamento quando eseguite su thread creati dallo sviluppatore, ma non sono attualmente tenuti a farlo. Tale requisito sarà aggiunto nella prossima versione di questa specifica. Si avvisano gli sviluppatori che, in base a questa capacità, i thread creati dall'applicazione non sono consigliati, in quanto non è portabile.
Non portatile significa che può essere presente in un server ma non in un altro.
Quando si desidera fare ricevere messaggi con JMS al di fuori di un MDB è possibile utilizzare quattro metodi in javax.jms.MessageConsumer
:
#receiveNoWait()
possibile per questo in un thread del contenitore, non bloccare, ma è come sbirciare . Se non è presente alcun messaggio, restituisce semplicemente null
. Questo non è molto adatto per ascoltare i messaggi.
#receive(long)
puoi farlo in un thread contenitore, esso blocca. In genere non si desidera bloccare le attese in un thread contenitore. Ancora una volta non molto adatto per l'ascolto di messaggi.
#receive()
, questo blocco può durare indefinitamente. Ancora una volta non molto adatto per l'ascolto di messaggi.
#setMessageListener()
questo è ciò che si desidera, ottenere una richiamata quando arriva un messaggio. Tuttavia, a meno che la libreria non possa collegarsi al server delle applicazioni, questo non sarà un thread contenitore. Gli hook nel server delle applicazioni sono disponibili solo tramite JCA agli adattatori di risorse.
Quindi sì, può funzionare, ma non è garantito e ci sono molte cose che potrebbero rompersi.
'Tuttavia, questo ha diversi svantaggi come JMS supporta solo il blocco legge e la primavera ha quindi bisogno di girare su di essa la propria discussioni che è totalmente supportato (anche in Tomcat) e può rompere le transazioni, la sicurezza, naming (JNDI) e caricamento della classe (che a sua volta può interrompere il remoting). Posso mostrarmi dove l'hai trovato? Sono sicuro che alcune persone usano Spring con un broker di messaggi indipendente senza App Server. Cercando di scoprire se qualcuno ha sollevato questo problema ovunque. Non sto dicendo che hai torto! :-) Cercando di ottenere più informazioni. –