JMS(Jboss Messaging)的一点使用心得(十一)Spring扩展应用-可自动重连的JmsMessageListenerContainer的另一种实现

来源:互联网 发布:柠檬云财税软件 编辑:程序博客网 时间:2024/05/16 15:59
为什么要做这个东西的原因就不说了,有兴趣的话可以看看我的另一篇文章
[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>
原创粉丝点击