SpringBoot中ApplicationEvent和ApplicationListener
假如在某业务中,需要发邮件,或者单独记录日志,但是呢,邮件并不重要,发送成功最好,不成功拉倒的那种。前提是不能影响主业务的正常结束。(其实是记录了一个不是很重要的日志,用到的时候需要单独记录统计的);
据说消息队列可以做很多事,但是!我不会!!!再说了就为了这点事加上消息队列,不太合适吧。
springboot 2.3.9.RELEASE
(全是抄来的)
先定义事件:MyEvent 继承ApplicationEvent:
private String msg;
public MyEvent(Object source, String msg) {
super(source);
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
监听:MyListener:
@Component
public class MyListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent myEvent) {
String threaid = Thread.currentThread().getName();
String msg = myEvent.getMsg();
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());
System.out.println("时间:"+format+"线程:"+threaid+"接收消息:"+msg);
}
}
在调用处 写在controller里了:applicationContext.publishEvent(new MyEvent(this,msg));
在idea里面调用试一下:GET http://localhost:8008/event?msg=“这是一条消息”;
GET http://localhost:8008/event?msg=%22%E8%BF%99%E6%98%AF%E4%B8%80%E6%9D%A1%E6%B6%88%E6%81%AF%22
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 7
Date: Thu, 27 May 2021 02:59:39 GMT
Keep-Alive: timeout=60
Connection: keep-alive
MyEvent
已经正常返回了MyEvent;
看下控制台:
当前线程:http-nio-8008-exec-3
时间:2021-05-27 10:59:39:543线程:http-nio-8008-exec-3接收消息:"这是一条消息"
MyEvent结束
哇!非常完美;
那如果有异常呢?试下看看!
在MyListener加了两行代码;
String str=null ;
int r = str.length();
返回了错误信息:
{
"timestamp": "2021-05-27T03:04:27.586+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/event"
}
控制台里呢?
当前线程:http-nio-8008-exec-6
时间:2021-05-27 11:04:27:556线程:http-nio-8008-exec-6接收消息:"这是一条消息"
2021-05-27 11:04:27.574 ERROR 12592 --- [nio-8008-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
......省略
想要的 结果 >>>MyEvent结束 但是没有打印出来,那这就不对了啊!
异步!(为什么呢,我也不知道。。。)
加@Async注解;还需在启动类加:@EnableAsync ;
现在可以了,看到了响应回来的 MyEvent;
控制台:事件结束之后报错了;是我想要的结果;(不要我为什么不捕获异常,,,我也不知道,可能就是单纯的不想吧!)
当前线程:http-nio-8008-exec-1
MyEvent结束
时间:2021-05-27 11:11:29:623线程:task-1接收消息:"这是一条消息"
2021-05-27 11:11:29.630 ERROR 832 --- [ task-1] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void com.act.eventAndListener.MyListener.onApplicationEvent(com.act.eventAndListener.MyEvent)
java.lang.NullPointerException: null
at com.act.eventAndListener.MyListener.onApplicationEvent(MyListener.java:22) ~[classes/:na]
...省略
今天不想写了。。。改天继续吧。。。
算了,写完吧,,,
然后,重新写了SendMail 、MailEvent、MailListener;
SendMail就一个实体,随便定义了几个属性;(这就不用写了,省略吧)接着是:
public class MailEvent extends ApplicationEvent {
private SendMail sendMail;
public MailEvent(Object source,SendMail sendMail) {
super(source);
this.sendMail=sendMail;
}
public SendMail getSendMail() {
return sendMail;
}
public void setSendMail(SendMail sendMail) {
this.sendMail = sendMail;
}
}
//==============================分割线====================================
@Component
public class MailListener implements ApplicationListener<MailEvent> {
@Async
@Override
public void onApplicationEvent(MailEvent mailEvent) {
SendMail sendMail = mailEvent.getSendMail();
String threaid = Thread.currentThread().getName();
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());
System.out.println("时间:"+format+";线程:"+threaid+";SendMail: " + sendMail);
if (sendMail.getRecevier() != "Tom") {
System.out.println("发送成功!");
} else {
String str = null;
str.length();
}
}
}
String threaid = Thread.currentThread().getName();
System.out.println("当前线程:"+threaid);
SendMail mail = new SendMail("zs", "lisi", new Date(), msg);
applicationContext.publishEvent(new MailEvent(this,mail));
System.out.println("mail:publishEvent"+mail);
mail.setRecevier("Tom");
applicationContext.publishEvent(new MailEvent(this,mail));
System.out.println("mail:publishEvent"+mail);
return "MyEvent";
哇!两个人名,一个叫lisi,一个叫Tom;那就应该有一个正常一个异常啊。信心满满去运行了一下!
GET http://localhost:8008/event?msg=%22%E8%BF%99%E6%98%AF%E4%B8%80%E6%9D%A1%E6%B6%88%E6%81%AF%22
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 7
Date: Thu, 27 May 2021 05:58:21 GMT
Keep-Alive: timeout=60
Connection: keep-alive
MyEvent
正常响应,没问题;
继续往下看:
当前线程:http-nio-8008-exec-3
------------------------------------------------------------
mail:publishEventSendMail{sender='zs', recevier='lisi', date=Thu May 27 13:58:21 CST 2021, msg='"这是一条消息"'}
------------------------------------------------------------
mail:publishEventSendMail{sender='zs', recevier='Tom', date=Thu May 27 13:58:21 CST 2021, msg='"这是一条消息"'}
------------------------------------------------------------
时间:2021-05-27 13:58:21:294;线程:task-1;SendMail: SendMail{sender='zs', recevier='Tom', date=Thu May 27 13:58:21 CST 2021, msg='"这是一条消息"'}
------------------------------------------------------------
时间:2021-05-27 13:58:21:294;线程:task-2;SendMail: SendMail{sender='zs', recevier='Tom', date=Thu May 27 13:58:21 CST 2021, msg='"这是一条消息"'}
------------------------------------------------------------
2021-05-27 13:58:21.302 ERROR 4344 --- [ task-2] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void com.act.eventAndListener.MailListener.onApplicationEvent(com.act.eventAndListener.MailEvent)
java.lang.NullPointerException: null
异常信息省略。。。。。。
------------------------------------------------------------
2021-05-27 13:58:21.302 ERROR 4344 --- [ task-1] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void com.act.eventAndListener.MailListener.onApplicationEvent(com.act.eventAndListener.MailEvent)
java.lang.NullPointerException: null
异常信息省略。。。。。。
两个异常?不对啊,第一个 recevier=‘lisi’,第二个 recevier=‘Tom’,第一个应该正常的啊,这是在controller里面输出的,在MailListener里面也有输出。。。但是怎么变了?
两个recevier='Tom’了?我的lisi呢?
难道是监听到事件的时候,已经执行了mail.setRecevier(“Tom”);?
看看是不是这样原因:Thread.sleep(2000);哈?!
果然:
当前线程:http-nio-8008-exec-1
mail:publishEventSendMail{sender='zs', recevier='lisi', date=Thu May 27 14:42:16 CST 2021, msg='"这是一条消息"'}
时间:2021-05-27 14:42:16:627;线程:task-1;SendMail: SendMail{sender='zs', recevier='lisi', date=Thu May 27 14:42:16 CST 2021, msg='"这是一条消息"'}
发生成功!
mail:publishEventSendMail{sender='zs', recevier='Tom', date=Thu May 27 14:42:16 CST 2021, msg='"这是一条消息"'}
时间:2021-05-27 14:42:18:631;线程:task-2;SendMail: SendMail{sender='zs', recevier='Tom', date=Thu May 27 14:42:16 CST 2021, msg='"这是一条消息"'}
2021-05-27 14:42:18.639 ERROR 32 --- [ task-2] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void com.act.eventAndListener.MailListener.onApplicationEvent(com.act.eventAndListener.MailEvent)
java.lang.NullPointerException: null
瞎搞~
想看源码,您看,我配吗?
(我很菜,请大佬们多怼几句)
闲着没事瞎搞就不会抑郁了,哈哈哈哈~