JMS(Jboss Messaging)的一點使用心得(十一)Spring擴展應用-可自動重連的JmsMessageListenerContainer的另一種實現

爲什麼要做這個東西的原因就不說了,有興趣的話可以看看我的另一篇文章
[http://blog.csdn.net/supersue/archive/2007/11/24/1901203.aspx]

這種實現的原理是利用Jms Connection的ExceptionListen機制,只在發生錯誤的時候纔去Check和重連,系統開銷會小一些。

以下是代碼
DCJmsMessageListenerContainer.java
package jms.receiver;

import javax.jms.Connection;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;

import org.springframework.jms.JmsException;
import org.springframework.jms.listener.serversession.ServerSessionMessageListenerContainer;


public class DCJmsMessageListenerContainer extends ServerSessionMessageListenerContainer
implements ExceptionListener {

    
/** interval */
    
private long interval = 300000;

    
private CheckConnectionThread checker;
    
    
/** ClassLoader */
    
private ClassLoader classLoader;
    
    
/** ExceptionListener */
    
private ExceptionListener exListener;

    
public void setInterval(long interval) {
        
this.interval = 60000 * interval;
    }


    
public void setExListener(ExceptionListener exListener) {
        
this.exListener = exListener;
    }


    @Override
    
public void afterPropertiesSet() {
        
super.afterPropertiesSet();
        
this.classLoader = Thread.currentThread().getContextClassLoader();
    }


    @Override
    
protected Connection createConnection() throws JMSException {
        Connection conn 
= super.createConnection();
        
if (this.exListener == null{
            conn.setExceptionListener(
this);
        }
 else {
            conn.setExceptionListener(
this.exListener);
        }

        
return conn;
    }


    @Override
    
public void destroy() {
        
if (this.checker != null{
            
this.checker.shutdown();
            
this.checker = null;
        }


        
super.destroy();
    }


    
public void refreshConnection() {
        
try {
            
this.logger.info(this.getBeanName() + " RefreshConnection Begin.");
            
if (this.checker == null || !this.checker.isCheckRun()) {
                
super.refreshSharedConnection();
                
super.initialize();
            }

            
this.logger.info(this.getBeanName() + " RefreshConnection Succeed.");
        }
 catch (JMSException e) {
            
this.logger.error(this.getBeanName() + " [Digitalcinema JMS Failover]", e);
        }

    }


    
public void onException(JMSException e) {
        
this.logger.error(this.getBeanName() + " Connection Error: " + e.getMessage());
        
if (this.checker != null{
            
this.checker.shutdown();
            
this.checker = null;
        }


        
this.checker = new CheckConnectionThread();
        
this.checker.setDaemon(true);
        
this.checker.setContextClassLoader(this.classLoader);
        
this.checker.start();
    }


    
public void handleException(JMSException e) {
        
this.logger.error(this.getBeanName() + " Connection Error: " + e.getMessage());
        
if (this.checker == null || !this.checker.isCheckRun()) {
            
this.checker = new CheckConnectionThread();
            
this.checker.setDaemon(true);
            
this.checker.setContextClassLoader(this.classLoader);
            
this.checker.start();
        }

    }


    
private class CheckConnectionThread extends Thread {
        
/** checkRunFlg */
        
private volatile boolean checkRunFlg = true;

        
public void shutdown() {
            
this.checkRunFlg = false;
            logger.info(DCJmsMessageListenerContainer.
this.getBeanName()
                    +
 " CheckConnectionThread Stoped!");
            
this.interrupt();
        }


        
public boolean isCheckRun() {
            
return this.checkRunFlg;
        }


        @Override
        
public void run() {
            logger.info(DCJmsMessageListenerContainer.
this.getBeanName()
                            +
 " CheckConnectionThread Started!");
            
this.checkRunFlg = true;

            
while (this.checkRunFlg) {
                
try {
                    logger.info(DCJmsMessageListenerContainer.
this.getBeanName() 
                                
+ " [Digitalcinema JMS Failover] Refresh Shared Connection");
                    DCJmsMessageListenerContainer.
this.refreshSharedConnection();
                    logger.info(DCJmsMessageListenerContainer.
this.getBeanName() 
                                
+ " [Digitalcinema JMS Failover] Container Initialize");
                    DCJmsMessageListenerContainer.
this.initialize();
                    
this.checkRunFlg = false;
                    
break;
                }
 catch (JmsException e) {
                    logger.info(DCJmsMessageListenerContainer.
this.getBeanName()
                                   +
 " [Digitalcinema JMS Failover]", e);
                    
try {
                        Thread.sleep(interval);
                    }
 catch (InterruptedException ie) {
                        logger.error(DCJmsMessageListenerContainer.
this.getBeanName() 
                                     
+ " [Digitalcinema JMS Failover]", ie);
                    }

                }
 catch (JMSException e) {
                    logger.info(DCJmsMessageListenerContainer.
this.getBeanName()
                          
+ " [Digitalcinema JMS Failover]", e);
                    
try {
                        Thread.sleep(interval);
                    }
 catch (InterruptedException ie) {
                        logger.error(DCJmsMessageListenerContainer.
this.getBeanName() 
                                     
+ " [Digitalcinema JMS Failover]", ie);
                    }

                }

            }

        }

    }

}


在Spring的配置文件中可以這樣配置
    <bean id="exListenerContainerQueue" lazy-init="true" 
        class
="jms.receiver.DCJmsMessageListenerContainer">
        
<property name="connectionFactory" ref="myConnectionFactory" />
        
<property name="destinationName" value="B" />
        
<property name="messageListener" ref="messageListener" />
        
<property name="sessionTransacted" value="true" />
    
</bean>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章