zoukankan      html  css  js  c++  java
  • 基于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     @Autowired
    106     public void setJmsTemplate(JmsTemplate jmsTemplate) {
    107         AsyncUtils.jmsTemplate = jmsTemplate;
    108     }
    109     @Autowired
    110     @Qualifier("sendMailDestination")
    111     public void setSendMailDestination(Destination sendMailDestination) {
    112         AsyncUtils.sendMailDestination = sendMailDestination;
    113     }
    114     @Autowired
    115     @Qualifier("LoginLogDestination")
    116     public void setLoginLogDestination(Destination loginLogDestination) {
    117         LoginLogDestination = loginLogDestination;
    118     }
    119     @Autowired
    120     @Qualifier("normalLogDestination")
    121     public void setNormalLogDestination(Destination normalLogDestination) {
    122         AsyncUtils.normalLogDestination = normalLogDestination;
    123     }
    124     @Autowired
    125     @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>
  • 相关阅读:
    BZOJ_3171_[Tjoi2013]循环格_最小费用最大流
    BZOJ_1150_[CTSC2007]数据备份Backup_堆+贪心
    BZOJ_1576_[Usaco2009 Jan]安全路经Travel&&BZOJ_3694_最短路_树链剖分+线段树
    BZOJ_4802_欧拉函数_MR+pollard rho+欧拉函数
    BZOJ_3667_Rabin-Miller算法_Mille_Rabin+Pollard rho
    BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP
    BZOJ_1229_[USACO2008 Nov]toy 玩具_三分+贪心
    BZOJ_2160_拉拉队排练_manacher
    [转载]Linux软件包及dpkgapt等方法
    服务器基础认知杂谈及一小点运维相关
  • 原文地址:https://www.cnblogs.com/libaoting/p/4107638.html
Copyright © 2011-2022 走看看