深入理解PooledConnectionFactory CachingConnectionFactory SingleConnectionFactory
PooledConnectionFactory實現ConnectionFactory接口。為因JmsTemlate每次發送消息時都會重新創建連接,創建connection,session,創建productor。這是一個非常耗性能的地方,特別是大數據量的情況下。因此出現了PooledConnectionFactory。這個類只會緩存connection,session和productor,不會緩存consumer。因此只適合於生產者發送消息。那為什么不緩存consumer呢?官方解釋是由於消費者一般是異步的,也就是說,broker代理會把生產者發送的消息放在一個消息者的預取緩存中。當消息者准備好的時候就會從這個預取緩存中取出來進行處理。我想,這個只是在要求消息處理的及時性不是特別高的情況下。如果希望處理能夠提高速度,自然也可以從這部分提高效率,減小不斷創建consumer的時間(大數據量的情況下)。
CachingConnectionFactory類擴展自SingleConnectionFactory,主要用於提供緩存JMS資源功能。具體包括messageProducer、MessageConsumer和Session的緩存功能。
publicclassCachingConnectionFactoryextendsSingleConnectionFactory{
privateint sessionCacheSize =1;
privateboolean cacheProducers =true;
privateboolean cacheConsumers =true;
privatevolatileboolean active =true;
privatefinalMap cachedSessions =newHashMap();
Spring中發送消息的核心是JmsTemplate,然而Jmstemplate的問題是在每次調用時都要打開/關閉session和producter,效率很低,所以引申出了PooledConnectionFactory連接池,用於緩存session和producter。然而這還不是最好的。從spring2.5.3版本后,Spring又提供了CachingConnectionFactory,這才是首選的方案。然而CachingConnectionFactory有一個問題必須指出,默認情況下,CachingConnectionFactory只緩存一個session,在它的JavaDoc中,它聲明對於低並發情況下這是足夠的。與之相反,PooledConnectionFactory的默認值是500。這些設置,在很多情況下,需要親自去測試並驗證。我將其設置為100,對我來說還是很不錯。
SingleConnectionFactory類實現了ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory,ExceptionListener接口。
Spring提供ConnectionFactory接口的一個實現,SingleConnectionFactory, 它將在所有的createConnection()調用中返回同一個相同的共享連接對象, 並且忽略Connection.close()和stop()的調用。根據JMS連接模型,這是完全線程安全的(相反,如JDBC)。這個共享連接能夠在出現異常時自動恢復創建一個新的共享連接。可以通過SingleConnectionFactory的構造函數中傳入Connection對象或者 ConnectionFactory對象,用來創建被代理的連接對象。 SingleConnectionFactory.createConnection方法返回的連接是個代理,它忽略了對stop和close方法的調用 (連接會在SingleConnectionFactory.destroy方法中關閉)。
protectedConnection getSharedConnectionProxy(Connection target){
List classes =newArrayList(3);
classes.add(Connection.class);
if(target instanceofQueueConnection){
classes.add(QueueConnection.class);
}
if(target instanceofTopicConnection){
classes.add(TopicConnection.class);
}
return(Connection)Proxy.newProxyInstance(
Connection.class.getClassLoader(),
(Class[]) classes.toArray(newClass[classes.size()]),
newSharedConnectionInvocationHandler(target));
}
這在測試和獨立的環境中相當有用, 因為同一個連接可以被用於跨多個監聽容器的JmsTemplate調用以跨越多個事務。 SingleConnectionFactory接受一個通常來自JNDI的標准ConnectionFactory的引用。
另外spring的消息監聽容器都支持一個共享的connection在多個監聽容器中使用。結合SingleConnectionFactory才真正讓人感受到跨多個監聽容器共享同一個JMS連接的功能。
在Java EE環境中,SingleConnectionFactory將把Connection和Session放到緩沖池中,因此這些資源在事務中得到了有效的復用。在獨立環境中使用Spring的 SingleConnectionFactory 會存在共享的JMS Connection,但每個事務有自己獨立的 Session。另外可以考慮使用供應商特定的池適配器,,如ActiveMQ的 PooledConnectionFactory 類。
SingleConnectionFactory的reconnectOnException屬性用來指定是否在連接拋出JMSException的時候,對連接進行重置,重置后如果再調用createConnection方法,那么會返回一個新的連接。
SingleConnectionFactory不支持定義用戶名和密碼。
