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

一般的实现方案

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

 import java.util.Date;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.apache.activemq.command.ActiveMQMapMessage;
import org.apache.activemq.command.ActiveMQObjectMessage;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
@Component
public class AsyncUtils {
private static Logger log = LoggerFactory.getLogger(AsyncUtils.class);
private static JmsTemplate jmsTemplate;
private static Destination sendMailDestination;
private static Destination LoginLogDestination;
private static Destination normalLogDestination;
private static Destination pushNotificationDestination;
public static void log(String type,String operate){
if(!SystemConfigFromDB.getBoolean(SystemConfigFromDB.NEED_NORMAL_LOG)){
return;
}
try{
User user = (User) SecurityUtils.getSubject().getSession().getAttribute("loginUser");
if(user==null){
return;
}
OperateLog log = new OperateLog(user.getId(), user.getName(), operate,type, user.getLastLoginIp());
final ActiveMQObjectMessage message = new ActiveMQObjectMessage();
message.setObject(log);
//AsycWorkFactory.sendMessage(message, AsycWork.NORMAL_LOG);
jmsTemplate.send(normalLogDestination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return message;
}
});
}catch (Exception e) {
log.error("日志记录出错!", e);
}
}
public static void sendMail(String address,String title,String content){
if(!SystemConfigFromDB.getBoolean(SystemConfigFromDB.NEED_SEND_MAIL)){
return;
}
try{
final ActiveMQMapMessage message = new ActiveMQMapMessage();
message.setString("address", address);
message.setString("title", title);
message.setString("content", content);
//AsycWorkFactory.sendMessage(message, AsycWork.EMAIL);
jmsTemplate.send(sendMailDestination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return message;
}
});
}catch (Exception e) {
log.error("邮件发送出错!",e);
}
}
public static void loginLog(String uid,String ip,Date date){
if(!SystemConfigFromDB.getBoolean(SystemConfigFromDB.NEED_LOG_CLIENTUSER_LOGINLOG)){
return;
}
try{
final ActiveMQMapMessage message = new ActiveMQMapMessage();
message.setString("uid", uid);
message.setString("ip", ip);
message.setString("date", DateUtils.formatDateTime(date, "yyyy-MM-dd HH:mm:ss"));
//AsycWorkFactory.sendMessage(message, AsycWork.LOGIN_LOG);
jmsTemplate.send(LoginLogDestination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return message;
}
});
}catch (Exception e) {
log.error("邮件发送出错!",e);
}
}
public static void pushNotification(String id,String content){
if(!SystemConfigFromDB.getBoolean(SystemConfigFromDB.NEED_LOG_CLIENTUSER_LOGINLOG)){
return;
}
try{
final ActiveMQMapMessage message = new ActiveMQMapMessage();
message.setString("id", id);
message.setString("content", content);
jmsTemplate.send(normalLogDestination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return message;
}
});
}catch (Exception e) {
log.error("消息推送出错!",e);
}
}
@Autowired
public void setJmsTemplate(JmsTemplate jmsTemplate) {
AsyncUtils.jmsTemplate = jmsTemplate;
}
@Autowired
@Qualifier("sendMailDestination")
public void setSendMailDestination(Destination sendMailDestination) {
AsyncUtils.sendMailDestination = sendMailDestination;
}
@Autowired
@Qualifier("LoginLogDestination")
public void setLoginLogDestination(Destination loginLogDestination) {
LoginLogDestination = loginLogDestination;
}
@Autowired
@Qualifier("normalLogDestination")
public void setNormalLogDestination(Destination normalLogDestination) {
AsyncUtils.normalLogDestination = normalLogDestination;
}
@Autowired
@Qualifier("pushNotificationDestination")
public void setPushNotificationDestination(
Destination pushNotificationDestination) {
AsyncUtils.pushNotificationDestination = pushNotificationDestination;
}
}

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

 @Component
public class EmailListener implements MessageListener {
private static Logger log = LoggerFactory.getLogger(EmailListener.class);
@Override
public void onMessage(Message message) {
ActiveMQMapMessage msg = (ActiveMQMapMessage) message;
try {
String address = msg.getString("address");
String title = msg.getString("title");
String content = msg.getString("content");
Constants.sendMail(address, title, content);
} catch (Exception e) {
log.error("异步邮件发送异常", e);
}
}
}

使用方式:

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

Spring配置文件:

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:core="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.9.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.1.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<!-- ActiveMQ 异步任务 -->
<context:annotation-config/>
<!-- 存放异步操作相关需要Spring管理的类的包 -->
<context:component-scan base-package="com.xxx.core.async" />
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.7.21:61616" />
</bean>
<!-- 带连接池的JMS链接工厂 -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="targetConnectionFactory" />
<property name="maxConnections" value="10" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="pooledConnectionFactory" />
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="sendMailDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="SendEmail"/>
</bean>
<bean id="LoginLogDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="LoginLog"/>
</bean>
<bean id="normalLogDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="NormalLog"/>
</bean>
<bean id="pushNotificationDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="Notification"/>
</bean>
<!-- 消息监听容器 -->
<bean id="jmsEmailContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="sendMailDestination" />
<property name="messageListener" ref="emailListener" /> <!-- 设置监听对象 -->
</bean>
<bean id="jmsLoginLogContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="LoginLogDestination" />
<property name="messageListener" ref="loginLogListener" /> <!-- 设置监听对象 -->
</bean>
<bean id="jmsNormalLogContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="normalLogDestination" />
<property name="messageListener" ref="normalLogListener" /> <!-- 设置监听对象 -->
</bean>
<bean id="jmsNotificationContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="pushNotificationDestination" />
<property name="messageListener" ref="pushNotificationListener" /> <!-- 设置监听对象 -->
</bean>
</beans>
上一篇:HTML5 Application cache初探和企业应用启示


下一篇:代码整洁之道(一)最佳实践小结