使用场景
我这边推荐你的场景是异步的方式来做。
比方你要进行登录,如果你登录了还需要发送邮件,比方你确定你只会做这一个事情而且以后不会增加了,那你就不需要基于事件去做,你可以写一个异步线程。
但是如果你的登录需要做很多事情,比方发送邮件,微信通知,发送短信等等,并且以后你还会增加,那么这时候比较推荐的是使用event事件来做,因为他非常方便以后的扩展。
推荐
推荐使用补充哪里的代码,少些一个类
定义事件(该类不需要写)
package com.jm.test.applicationEvent;
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
public class ActionEvent extends ApplicationEvent {
@Getter
private String msg;
public ActionEvent(Object source,String msg) {
super(source);
this.msg = msg;
System.out.println("action event created");
}
}
定义发布者
package com.jm.test.applicationEvent.publicsher;
import com.jm.test.applicationEvent.ActionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class ActionPublisher {
@Autowired
private ApplicationEventPublisher publisher;
public void publish(String msg){
publisher.publishEvent(new ActionEvent(this,msg));
}
}
定义监听者
通过@order注解,来觉得优先级
package com.jm.test.applicationEvent.listener;
import com.jm.test.applicationEvent.ActionEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
public class ActionListener {
@Order(2)
@EventListener
public void showAction(ActionEvent actionEvent){
String msg = actionEvent.getMsg();
System.out.println("监听者1:"+msg);
System.out.println("监听者线程="+Thread.currentThread().getId());
}
@Order(1)
@EventListener(ActionEvent.class)
public void showAction2(ActionEvent actionEvent){
String msg = actionEvent.getMsg();
System.out.println("监听者2:"+msg);
System.out.println("监听者线程="+Thread.currentThread().getId());
}
}
异步监听
听过异步注解,来设置异步的方式监听,但此时@Order的注解就会失效了,因为异步了,就没有优先级了
package com.jm.test.applicationEvent.listener;
import com.jm.test.applicationEvent.ActionEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
@Component
@EnableAsync
public class ActionListener {
@Order(2)
@Async
@EventListener
public void showAction(ActionEvent actionEvent){
String msg = actionEvent.getMsg();
System.out.println("监听者1:"+msg);
System.out.println("监听者线程="+Thread.currentThread().getId());
}
@Order(1)
@Async
@EventListener(ActionEvent.class)
public void showAction2(ActionEvent actionEvent){
String msg = actionEvent.getMsg();
System.out.println("监听者2:"+msg);
System.out.println("监听者线程="+Thread.currentThread().getId());
}
}
测试
package com.jm.test.applicationEvent;
import com.jm.test.applicationEvent.publicsher.ActionPublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ActionEventController {
@Autowired
private ActionPublisher actionPublisher;
@GetMapping("/testActionEvent")
public void testActionEvent(){
actionPublisher.publish("打篮球");
System.out.println("发送者线程="+Thread.currentThread().getId());
}
}
方式二 补充(不需要event)
1.1 监听的时间消息
package com.jm.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EventMsg {
private Long id;
private String name;
}
1.2 推送消息
package com.jm.event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.SpringApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Jeremy
*/
@RestController
public class EventPublisher {
@Autowired
private ApplicationEventPublisher publisher;
@GetMapping("/event/publisher")
public void publisher(){
// publisher.publishEvent(new MyEvent(this,new EventMsg(1L,"123")));
System.out.println(Thread.currentThread().getName());
publisher.publishEvent(new EventMsg(1L,"123"));
}
}
1.3 监听消息
package com.jm.event;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
@Component
@EnableAsync
public class MyEventListener {
@EventListener(EventMsg.class)
public void evnetListener(EventMsg event){
System.out.println(Thread.currentThread().getName());
System.out.println(event);
}
@EventListener(EventMsg.class)
@Async
public void evnetListener1(EventMsg event){
System.out.println(Thread.currentThread().getName());
System.out.println(event);
}
}
三. 实战(推荐)
3.1 定义登录事件
package com.jm.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 登录事件
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginEvent {
private String username;
private String address;
}
3.2 推送事件
package com.jm.event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Jeremy
*/
@RestController
public class EventPublisher {
@Autowired
private ApplicationEventPublisher publisher;
@GetMapping("/event/login")
public void login(){
// publisher.publishEvent(new MyEvent(this,new EventMsg(1L,"123")));
System.out.println(Thread.currentThread().getName());
// publisher.publishEvent(new EventMsg(1L,"123"));
publisher.publishEvent(new LoginEvent("张三","上海"));
System.out.println(11234);
}
}
3.3 监听事件
如果以后登录还需要进行,其他的操作或者进行登录业务的补充。
只要在这个里面添加一个监听。
package com.jm.event;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
@Component
@EnableAsync
public class MyEventListener {
/**
* 登录进行邮件发送
* @param event
*/
@EventListener(LoginEvent.class)
@Async
public void sendEmail(LoginEvent event){
System.out.println(Thread.currentThread().getName()+"=发送邮件+"+event);
}
/**
* 登录进行微信通知
* @param event
*/
@EventListener(LoginEvent.class)
@Async
public void sendWeChat(LoginEvent event){
System.out.println(Thread.currentThread().getName()+"=微信通知+"+event);
}
}