spring发布和接收定制的事件(spring事件传播)

事件

Spring事件处理一般过程:

  • 定义Event类,继承org.springframework.context.ApplicationEvent。
  • 编写发布事件类Publisher,实现org.springframework.context.ApplicationContextAware接口。
  • 覆盖方法setApplicationContext(ApplicationContext applicationContext)和发布方法publish(Object obj)。
  • 定义时间监听类EventListener,实现ApplicationListener接口,实现方法onApplicationEvent(ApplicationEvent event)。

解释

Spring中提供了ApplicationEventPublisher接口作为事件发布者,并且ApplicationContext实现了这个接口,担当起了事件发布者这一角色

Spring中提供一些Aware相关的接口,BeanFactoryAware、 ApplicationContextAware、ResourceLoaderAware、ServletContextAware等等,其中最常用到的是ApplicationContextAware。实现ApplicationContextAware的Bean,在Bean被初始后,将会被注入ApplicationContext的实例。ApplicationContextAware提供了publishEvent()方法,实现Observer(观察者)设计模式的事件传播机,提供了针对Bean的事件传播功能。通过Application.publishEvent方法,我们可以将事件通知系统内所有的ApplicationListener。

实现 事件 ApplicationEvent

smslog

public class SmsLog implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @TableId(value = "sms_log_id", type = IdType.AUTO)
    private Integer smsLogId;
    /**
     * 手机号
     */
    private String userPhone;
    /**
     * 短信内容
     */
    private String smsText;
    /**
     * 短信类型 0 注册 1 登陆
     */
    private int smsType;

    /**
     * 发送时间
     */
    private Date sendTime;
    /**
     * 发送状态 0 未发送 1发送成功 2发送失败
     */
    private Integer sendStatus;

    public SmsLog() {
    }

    public SmsLog(String userPhone, String smsText, int smsType) {
        this.userPhone = userPhone;
        this.smsText = smsText;
        this.smsType = smsType;
    }

    public SmsLog(String userPhone, String smsText, SmsTypeEnum smsType) {
        this.userPhone = userPhone;
        this.smsText = smsText;
        this.smsType = smsType.ordinal();
    }

    public Integer getSmsLogId() {
        return smsLogId;
    }

    public void setSmsLogId(Integer smsLogId) {
        this.smsLogId = smsLogId;
    }

    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }

    public String getSmsText() {
        return smsText;
    }

    public void setSmsText(String smsText) {
        this.smsText = smsText;
    }

    public int getSmsType() {
        return smsType;
    }

    public void setSmsType(int smsType) {
        this.smsType = smsType;
    }

    public void setSmsTypeEnum(SmsTypeEnum smsType) {
        this.smsType = smsType.ordinal();
    }

    public Date getSendTime() {
        return sendTime;
    }

    public void setSendTime(Date sendTime) {
        this.sendTime = sendTime;
    }

    public Integer getSendStatus() {
        return sendStatus;
    }

    public void setSendStatus(Integer sendStatus) {
        this.sendStatus = sendStatus;
    }

}
public class SendSmsEvent extends ApplicationEvent {

    private static final long serialVersionUID = 5819199428179496870L;
    private SmsLog smsSource;
    private boolean persistent=true;// 短信是否持久化

    public SendSmsEvent(Object source) {
        super(source);
    }

    public SendSmsEvent(Object source, SmsLog sms) {
        super(source);
        this.smsSource = sms;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public SmsLog getSmsSource() {
        return smsSource;
    }

    public boolean isPersistent() {
        return persistent;
    }

    /**
     * 设置短信是否持久化到库
     * 
     * @param persistent
     */
    public void setPersistent(boolean persistent) {
        this.persistent = persistent;
    }

}

实现 ApplicationContextAware接口

public final class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext springContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextHolder.springContext = applicationContext;
    }
    
    /**
     * 返回spring上下文环境对象
     * 
     * @return ApplicationContext
     */
    public static ApplicationContext getSpringContext() {
        return springContext;
    }

 /**
     * 发布事件到spring
     * @param event
     */
    public static void pushEvent(ApplicationEvent event) {
        springContext.publishEvent(event);
    }
}

可选:
还可以在xml配置下方便使用


实现ApplicationListener

@Component
public class SendSmsEventListener implements ApplicationListener {

    @Resource
    private ISmsLogService smsLogServiceImpl;

    private final Logger logger = LoggerFactory.getLogger(SendSmsEventListener.class);
    @Resource
    private ISmsSender yunPianSmsSender;

    /**
     * @param smsLog status 0成功,非0失败
     */
    @Override
    @Async
    public void onApplicationEvent(SendSmsEvent event) {
        SmsLog smsLog = event.getSmsSource();
        CallResult result = yunPianSmsSender.send(smsLog.getSmsText(), smsLog.getUserPhone());
        smsLog.setSendStatus(result.getStatus());
        smsLog.setSendTime(new Date());
        if (event.isPersistent()) {
            try {
                smsLogServiceImpl.save(smsLog);
            } catch (Exception e) {
                logger.error("发送短信出" + e.getMessage(), e);
            }
        }
    }

}

注解方式实现

事件

package com.ghgcn.event.service;

import org.springframework.context.ApplicationEvent;

public class DemoEvent extends ApplicationEvent {

    private String msg;

    public DemoEvent(Object source) {
        super(source);
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public DemoEvent(Object source, String msg) {
        super(source);
        this.msg = msg;
    }
}

发送者


@Component
public class DemoPulisher  {

    @Autowired
    ApplicationContext applicationContext;
    

    public void publish(ApplicationEvent applicationEvent){
        //applicationContext.publishEvent(applicationEvent);
        applicationContext.publishEvent(applicationEvent);
    }


}

配置

package com.ghgcn.event.service;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {"com.ghgcn.event"})
public class EventConfig {


}

监听器

package com.ghgcn.event.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class DemoEventListener implements ApplicationListener {
    private Logger logger = LoggerFactory.getLogger(DemoEventListener.class);



    @Override
    public void onApplicationEvent(DemoEvent event) {

        String msg=event.getMsg();
        logger.debug("onApplicationEvent   {}",event);
        logger.debug("onApplicationEvent   {}",event);
        logger.debug("onApplicationEvent   {}",event);
        logger.debug("onApplicationEvent   {}",event);
        logger.debug("onApplicationEvent   {}",event);
        logger.debug("onApplicationEvent   {}",event);
        logger.debug("onApplicationEvent   {}",event);

        logger.debug("onApplicationEvent   {}",msg);
        System.out.println("DemoEventListener   接收到的消息 "+event);
    }
}


测试

package com.ghgcn.event.test;

import com.ghgcn.event.service.DemoEvent;
import com.ghgcn.event.service.DemoPulisher;
import com.ghgcn.event.service.EventConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Date;

public class EventTest {

    public  static  void main(String [] args){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);


        DemoPulisher demoPulisher = context.getBean(DemoPulisher.class);

        demoPulisher.publish(new DemoEvent(new Date(),"魂牵梦萦 "));

        context.close();
    }
}


结果

17:46:26.821 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source. Returning [null]
17:46:26.822 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'demoPulisher'
17:46:26.823 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'demoEventListener'
17:46:26.823 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent   DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}
17:46:26.824 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent   DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}
17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent   DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}
17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent   DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}
17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent   DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}
17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent   DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}
17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent   DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}
17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent   魂牵梦萦 
DemoEventListener   接收到的消息 DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}

你可能感兴趣的:(spring发布和接收定制的事件(spring事件传播))