事件
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配置下方便使用
<bean id="springContext" class="com.ghgcn.cigarbox.support.SpringContextHolder"></bean>
实现ApplicationListener
@Component
public class SendSmsEventListener implements ApplicationListener<SendSmsEvent> {
@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<DemoEvent> {
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}