首页 > 代码库 > 基于Spring的异步系统实现方案

基于Spring的异步系统实现方案

一般的实现方案

发送异步消息所使用的工具类:

  1 import java.util.Date;  2 import javax.jms.Destination;  3 import javax.jms.JMSException;  4 import javax.jms.Message;  5 import javax.jms.Session;  6 import org.apache.activemq.command.ActiveMQMapMessage;  7 import org.apache.activemq.command.ActiveMQObjectMessage;  8 import org.apache.shiro.SecurityUtils;  9 import org.slf4j.Logger; 10 import org.slf4j.LoggerFactory; 11 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Qualifier; 13 import org.springframework.jms.core.JmsTemplate; 14 import org.springframework.jms.core.MessageCreator; 15 import org.springframework.stereotype.Component; 16 @Component 17 public class AsyncUtils { 18     private static Logger log = LoggerFactory.getLogger(AsyncUtils.class);  19     private static JmsTemplate jmsTemplate; 20     private static Destination sendMailDestination; 21     private static Destination LoginLogDestination; 22     private static Destination normalLogDestination; 23     private static Destination pushNotificationDestination; 24     public static void log(String type,String operate){ 25         if(!SystemConfigFromDB.getBoolean(SystemConfigFromDB.NEED_NORMAL_LOG)){ 26             return; 27         } 28         try{ 29             User user = (User) SecurityUtils.getSubject().getSession().getAttribute("loginUser"); 30             if(user==null){ 31                 return; 32             } 33             OperateLog log = new OperateLog(user.getId(), user.getName(), operate,type, user.getLastLoginIp()); 34             final ActiveMQObjectMessage message = new ActiveMQObjectMessage(); 35             message.setObject(log); 36             //AsycWorkFactory.sendMessage(message, AsycWork.NORMAL_LOG); 37             jmsTemplate.send(normalLogDestination, new MessageCreator() { 38                 @Override 39                 public Message createMessage(Session session) throws JMSException { 40                     return message; 41                 } 42             }); 43         }catch (Exception e) { 44             log.error("日志记录出错!", e); 45         } 46     } 47     public static void sendMail(String address,String title,String content){ 48         if(!SystemConfigFromDB.getBoolean(SystemConfigFromDB.NEED_SEND_MAIL)){ 49             return; 50         } 51         try{ 52             final ActiveMQMapMessage message = new ActiveMQMapMessage(); 53             message.setString("address", address); 54             message.setString("title", title); 55             message.setString("content", content); 56             //AsycWorkFactory.sendMessage(message, AsycWork.EMAIL); 57             jmsTemplate.send(sendMailDestination, new MessageCreator() { 58                 @Override 59                 public Message createMessage(Session session) throws JMSException { 60                     return message; 61                 } 62             }); 63         }catch (Exception e) { 64             log.error("邮件发送出错!",e); 65         } 66     } 67     public static void loginLog(String uid,String ip,Date date){ 68         if(!SystemConfigFromDB.getBoolean(SystemConfigFromDB.NEED_LOG_CLIENTUSER_LOGINLOG)){ 69             return; 70         } 71         try{ 72             final ActiveMQMapMessage message = new ActiveMQMapMessage(); 73             message.setString("uid", uid); 74             message.setString("ip", ip); 75             message.setString("date", DateUtils.formatDateTime(date, "yyyy-MM-dd HH:mm:ss")); 76             //AsycWorkFactory.sendMessage(message, AsycWork.LOGIN_LOG); 77             jmsTemplate.send(LoginLogDestination, new MessageCreator() { 78                 @Override 79                 public Message createMessage(Session session) throws JMSException { 80                     return message; 81                 } 82             }); 83         }catch (Exception e) { 84             log.error("邮件发送出错!",e); 85         } 86     } 87     public static void pushNotification(String id,String content){ 88         if(!SystemConfigFromDB.getBoolean(SystemConfigFromDB.NEED_LOG_CLIENTUSER_LOGINLOG)){ 89             return; 90         } 91         try{ 92             final ActiveMQMapMessage message = new ActiveMQMapMessage(); 93             message.setString("id", id); 94             message.setString("content", content); 95             jmsTemplate.send(normalLogDestination, new MessageCreator() { 96                 @Override 97                 public Message createMessage(Session session) throws JMSException { 98                     return message; 99                 }100             });101         }catch (Exception e) {102             log.error("消息推送出错!",e);103         }104     }105     @Autowired106     public void setJmsTemplate(JmsTemplate jmsTemplate) {107         AsyncUtils.jmsTemplate = jmsTemplate;108     }109     @Autowired110     @Qualifier("sendMailDestination")111     public void setSendMailDestination(Destination sendMailDestination) {112         AsyncUtils.sendMailDestination = sendMailDestination;113     }114     @Autowired115     @Qualifier("LoginLogDestination")116     public void setLoginLogDestination(Destination loginLogDestination) {117         LoginLogDestination = loginLogDestination;118     }119     @Autowired120     @Qualifier("normalLogDestination")121     public void setNormalLogDestination(Destination normalLogDestination) {122         AsyncUtils.normalLogDestination = normalLogDestination;123     }124     @Autowired125     @Qualifier("pushNotificationDestination")126     public void setPushNotificationDestination(127             Destination pushNotificationDestination) {128         AsyncUtils.pushNotificationDestination = pushNotificationDestination;129     }130 }

监听异步消息的监听器类(可以给每个类型的消息设定不同的监听器):

 1 @Component 2 public class EmailListener implements MessageListener { 3     private static Logger log = LoggerFactory.getLogger(EmailListener.class); 4     @Override 5     public void onMessage(Message message) { 6         ActiveMQMapMessage msg = (ActiveMQMapMessage) message; 7         try { 8             String address = msg.getString("address"); 9             String title = msg.getString("title");10             String content = msg.getString("content");11             Constants.sendMail(address, title, content);12         } catch (Exception e) {13             log.error("异步邮件发送异常", e);14         }15     }16 }

使用方式:

//异步发送邮件AsyncUtils.sendMail("邮件地址","主题","内容");//即可

Spring配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>   2 <beans xmlns="http://www.springframework.org/schema/beans"   3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4     xmlns:aop="http://www.springframework.org/schema/aop"   5     xmlns:core="http://activemq.apache.org/schema/core"   6     xmlns:jms="http://www.springframework.org/schema/jms"   7     xmlns:context="http://www.springframework.org/schema/context"   8     xmlns:lang="http://www.springframework.org/schema/lang"   9     xmlns:util="http://www.springframework.org/schema/util"  10     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  11         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  12         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  13         http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.9.0.xsd  14         http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.1.xsd  15         http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd  16         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">  17     <!-- ActiveMQ 异步任务 -->18     <context:annotation-config/>  19     <!-- 存放异步操作相关需要Spring管理的类的包 -->20     <context:component-scan base-package="com.xxx.core.async" />21      <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->  22     <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">  23         <property name="brokerURL" value="tcp://192.168.7.21:61616" />  24     </bean>  25     <!-- 带连接池的JMS链接工厂 -->  26     <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">  27         <property name="connectionFactory" ref="targetConnectionFactory" />  28         <property name="maxConnections" value="10" />  29     </bean>30     <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->  31     <bean id="connectionFactory"  32         class="org.springframework.jms.connection.SingleConnectionFactory">  33         <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->  34         <property name="targetConnectionFactory" ref="pooledConnectionFactory" />  35     </bean>  36     <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->  37     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  38         <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->  39         <property name="connectionFactory" ref="connectionFactory" />  40     </bean>  41     <bean id="sendMailDestination" class="org.apache.activemq.command.ActiveMQQueue">  42         <constructor-arg value="SendEmail"/>  43     </bean>  44     <bean id="LoginLogDestination" class="org.apache.activemq.command.ActiveMQQueue">  45         <constructor-arg value="LoginLog"/>  46     </bean>  47     <bean id="normalLogDestination" class="org.apache.activemq.command.ActiveMQQueue">  48         <constructor-arg value="NormalLog"/>  49     </bean>  50     <bean id="pushNotificationDestination" class="org.apache.activemq.command.ActiveMQQueue">  51         <constructor-arg value="Notification"/>  52     </bean>  53     <!-- 消息监听容器 -->  54     <bean id="jmsEmailContainer"  class="org.springframework.jms.listener.DefaultMessageListenerContainer">  55         <property name="connectionFactory" ref="connectionFactory" />  56         <property name="destination" ref="sendMailDestination" />  57         <property name="messageListener" ref="emailListener" />  <!-- 设置监听对象 -->58     </bean>  59     <bean id="jmsLoginLogContainer"  class="org.springframework.jms.listener.DefaultMessageListenerContainer">  60         <property name="connectionFactory" ref="connectionFactory" />  61         <property name="destination" ref="LoginLogDestination" />  62         <property name="messageListener" ref="loginLogListener" />  <!-- 设置监听对象 -->63     </bean>   64     <bean id="jmsNormalLogContainer"  class="org.springframework.jms.listener.DefaultMessageListenerContainer">  65         <property name="connectionFactory" ref="connectionFactory" />  66         <property name="destination" ref="normalLogDestination" />  67         <property name="messageListener" ref="normalLogListener" />  <!-- 设置监听对象 -->68     </bean>69     <bean id="jmsNotificationContainer"  class="org.springframework.jms.listener.DefaultMessageListenerContainer">  70         <property name="connectionFactory" ref="connectionFactory" />  71         <property name="destination" ref="pushNotificationDestination" />  72         <property name="messageListener" ref="pushNotificationListener" />  <!-- 设置监听对象 -->73     </bean>  74 </beans>

 

基于Spring的异步系统实现方案