自定义事件分发,执行耗时操作服务

来源:互联网 发布:传奇盗取管理权限软件 编辑:程序博客网 时间:2024/06/03 05:01

关于SpringMVC里面,进行自定义事件,分发处理耗时操作服务的示例解析

事件处理在spring的应用程序上下文(ApplicationContext )里面,是通过ApplicationEvent和ApplicationListener 实现的,spring本身的一些事件有ContextRefreshedEvent,ContextStartedEvent,ContextStoppedEvent, etc. 同时spring可以允许我们自定义事件,并进行事件的捕获及处理( 这种机制可以让我们做一些耗时操作的服务,或者消息服务之类的等),下面本人通过发送邮件服务对这个spring特性进行示例应用下。

1 . 首先自定义我们的邮件发送事件实体

package com.hisoka.applicationEvent;import org.springframework.context.ApplicationEvent;import com.hisoka.POJO.Email;/** * EmailMonitorEvent.java *  * @author: Hinsteny * @date: 2015年11月25日 * @copyright: 2015 All rights reserved. *  */public class EmailMonitorEvent extends ApplicationEvent {    /**     * serialVersionUID     * long     */    private static final long serialVersionUID = 7197120866146492975L;    private final String sendAddress;    private final Email email;    public EmailMonitorEvent(Object source, String sendAddress, Email email) {        super(source);        this.sendAddress = sendAddress;        this.email = email;    }    public String getSendAddress() {        return sendAddress;    }    public Email getEmail() {        return email;    }}

2 . 这里实现ApplicationEventPublisherAware,然后就可以触发并发布一个自定义事件

package com.hisoka.applicationEvent;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationEventPublisher;import org.springframework.context.ApplicationEventPublisherAware;import org.springframework.stereotype.Component;import com.hisoka.POJO.Email;import com.hisoka.support.email.MailSender;/** * EmailService.java *  * @author: Hinsteny * @date: 2015年11月25日 * @copyright: 2015 All rights reserved. *  */@Componentpublic class EmailService implements ApplicationEventPublisherAware {    private Logger logger = LoggerFactory.getLogger(EmailService.class);    @Autowired    MailSender mailSender;//发送邮件的工具类    private ApplicationEventPublisher publisher;    @Override    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {        this.publisher = applicationEventPublisher;    }    public void sendEmail(String toAddress, String title, String content) {        Email email = new Email();        email.setTitle(title);        email.setContent(content);        email.setToAddress(toAddress);        EmailMonitorEvent event = new EmailMonitorEvent(this, mailSender.getMailUser(), email);        logger.debug("publish send email Event!");        publisher.publishEvent(event);        // other service    }}

3 . 然后实现ApplicationListener接口,即接收我们的自定义事件及处理事件

package com.hisoka.applicationEvent;import java.io.IOException;import javax.annotation.Resource;import javax.mail.MessagingException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.context.ApplicationListener;import org.springframework.stereotype.Component;/** * EmailListNotifier.java *  * @author: Hinsteny * @date: 2015年11月25日 * @copyright: 2015 All rights reserved. *  */@Componentpublic class EmailListNotifier implements ApplicationListener<EmailMonitorEvent> {    private Logger logger = LoggerFactory.getLogger(EmailListNotifier.class);    @Resource    private EmailJob emailJob;//发送邮件的服务类    @Override    public void onApplicationEvent(EmailMonitorEvent event) {        try {            logger.debug("Just do send email service!");            emailJob.send(event.getEmail());        } catch (MessagingException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}

4 . 发送邮件的服务类代码

package com.hisoka.applicationEvent;import java.io.IOException;import java.util.HashMap;import java.util.Map;import javax.annotation.Resource;import javax.mail.MessagingException;import org.beetl.core.Configuration;import org.beetl.core.GroupTemplate;import org.beetl.core.Template;import org.beetl.core.resource.StringTemplateResourceLoader;import org.springframework.core.io.ClassPathResource;import org.springframework.stereotype.Component;import com.hisoka.POJO.Email;import com.hisoka.support.email.MailSender;import com.hisoka.utils.Strings;/** * @author: Hinsteny * @date: 2015年11月25日 * @copyright: 2015 All rights reserved. */@Componentpublic class EmailJob {    private static final String url = "email.tmpl";    @Resource    private MailSender mailSender;    public void send(Email email) throws MessagingException, IOException {        //邮件模板        String emailTemplate = Strings.getContentFromInputStream(new ClassPathResource(url).getInputStream(),"utf-8");        Map<String,Object> data = new HashMap<>();        data.put("totalRegister", 15);        StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader();        Configuration cfg = Configuration.defaultConfiguration();        GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);        Template t = gt.getTemplate(emailTemplate);        t.binding(data);        mailSender.send(email.getToAddress(), email.getTitle(), t.render());    }}

5 . 最后就是进行邮件发送的工具类

package com.hisoka.support.email;import java.util.Date;import java.util.Properties;import javax.mail.Authenticator;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.PasswordAuthentication;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import org.springframework.stereotype.Component;import com.hisoka.support.config.Config;/** * MailSender.java *  * @author: Hinsteny * @date: 2015年11月25日 * @copyright: 2015 All rights reserved. *  */@Componentpublic class MailSender {    @Config("mail.user")    private String mailUser;    @Config("mail.password")    private String mailPassword;    @Config("mail.host")    private String mailHost;    public String getMailUser() {        return mailUser;    }    public void setMailUser(String mailUser) {        this.mailUser = mailUser;    }    public String getMailPassword() {        return mailPassword;    }    public void setMailPassword(String mailPassword) {        this.mailPassword = mailPassword;    }    public String getMailHost() {        return mailHost;    }    public void setMailHost(String mailHost) {        this.mailHost = mailHost;    }    /**     * 邮件发送     *      * @param receiver 接收邮箱     * @param subject 主题     * @param content 内容     * @throws MessagingException     */    public void send(String receiver, String subject, String content) throws MessagingException {        Properties props = new Properties();        props.put("mail.smtp.auth", "true");        props.put("mail.smtp.host", mailHost);        props.put("mail.debug", "true");        Session session = Session.getInstance(props, new Authenticator() {            @Override            protected PasswordAuthentication getPasswordAuthentication() {                return new PasswordAuthentication(mailUser, mailPassword);            }        });        MimeMessage msg = new MimeMessage(session);        msg.setFrom(new InternetAddress(mailUser));        String[] arr = receiver.split(",|,");        InternetAddress[] address = new InternetAddress[arr.length];        for (int i = 0; i < arr.length; i++) {            address[i] = new InternetAddress(arr[i]);        }        msg.addRecipients(Message.RecipientType.TO, address);        msg.setSubject(subject);        msg.setSentDate(new Date());        msg.setContent(content, "text/html;charset=utf-8");        Transport.send(msg);    }}

上面我们在实际应用中,一般请求一个服务 (譬如上面EmailService的sendEmail方法),假如我们的发送邮件是一个耗时的操作 (查一些邮件内容需要的数据,做数据库记录等),这里我们要是等到所有事情做完并发完邮件,那客户端等待的时间就比较长了 (或者说客户体验不好,哈哈),并且客户端不需要发送邮件服务返回什么数据,那我们在这里可以先给客户端返回,把真正的邮件发送服务安排到一个事件处理里面 (这里一般还可以用多线程的方式去处理),这样很明显对客户端的响应就快速,友好多了嘛

关于spring的自定义事件分发处理的介绍就到这了,后面再学习更多的spring特性,哈哈

0 0