参考资料
1.https://www.cnblogs.com/cq-yangzhou/p/14648810.html
2.https://blog.csdn.net/qq_35387940/article/details/121315114
3.如果你还不知道如何控制springboot中bean的加载顺序,那你一定要看此篇
一. 使用场景
观察者模式主要作用在于实现业务的解耦。以用户注册的场景来举例子:
假设在用户注册完成时,需要给该用户发送邮件、发送优惠劵等等操作.
二.示例
2.1 创建自定义用户注册事件
import org.springframework.context.ApplicationEvent;
// 继承ApplicationEvent类,创建自定义用户注册事件
public class UserRegisterEvent extends ApplicationEvent {
// 注册成功的用户id
private String userId;
public UserRegisterEvent(Object source) {
super(source);
}
public UserRegisterEvent(Object source, String userId) {
super(source);
this.userId = userId;
}
// 获取用户id
public String getUserId() {
return userId;
}
}
2.2 监听用户自定义事件
⏹当事件发布者会触发多个事件的时候,可通过@Order
注解指定事件触发的顺序
⏹order越小,执行优先度越高
⏹不实现ApplicationListener
接口,给方法添加@EventListener
注解,也可以触发事件
⏹通过@Order
注解指定执行顺序的类,必须要实现ApplicationListener
接口,ApplicationListener
接口和@EventListener
注解搭配的使用的话,@Order
注解会失效
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(1)
public class EmailService implements ApplicationListener<UserRegisterEvent> {
// 监听UserRegisterEvent用户注册事件,当用户注册后,给用户发送邮件
@Override
public void onApplicationEvent(UserRegisterEvent event) {
String userId = event.getUserId();
// 模拟耗发送邮件耗时操作
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("给ID为" + userId + "的用户发送邮件");
}
}
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(2)
public class CouponService implements ApplicationListener<UserRegisterEvent> {
@Override
public void onApplicationEvent(UserRegisterEvent userRegisterEvent) {
String userId = userRegisterEvent.getUserId();
System.out.println("给ID为" + userId + "的用户发送优惠券");
}
}
通过@EventListener
接口实现的监听方法,可以把@Order
注解放到方法上
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
public class EmailService {
@Order(1)
@EventListener
public void addCoupon(UserRegisterEvent event) {
String userId = event.getUserId();
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("给ID为" + userId + "的用户发送邮件");
}
}
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
public class CouponService {
@Order(2)
@EventListener
public void addCoupon(UserRegisterEvent event) {
String userId = event.getUserId();
System.out.println("给ID为" + userId + "的用户发送优惠券");
}
}
2.3 创建事件发布对象
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
@Component
public class UserService implements ApplicationEventPublisherAware {
// 事件发布对象
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void register(String userId) {
// 当用户注册成功之后,发布自定义事件UserRegisterEvent,
applicationEventPublisher.publishEvent(new UserRegisterEvent(this, userId));
}
}
2.4 调用
@Component
public class ParamExecute implements CommandLineRunner {
@Autowired
private UserService service;
@Override
public void run(String... args) throws Exception {
// 模拟用户注册成功
String userId = "F202001";
service.register(userId);
}
}