观察者模式介绍
观察者模式介绍:当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式
观察者模式是发布订阅模式的一种特殊实现,发布订阅模式是在观察者模式的基础上做的优化升级
观察者模式Java版本简单实现参考链接:https://www.runoob.com/design-pattern/observer-pattern.html
SpringBoot实现
注意:此处业务场景为用户购买商品下单并增加对应购物积分
1.创建Event事件类
ShoppingEvent事件类
public class ShoppingEvent extends ApplicationEvent {
/**
* 调用祖先类构造 传入一个user对象
*/
private ShoppingEvent(User user) {
super(user);
}
/**
* 创建一个Event对象
*/
public static ShoppingEvent buildEvent(User user) {
return new ShoppingEvent(user);
}
}
ShoppingEvent的祖先类为EventObject源码如下
实际上就是一个构造方法、getSource和toString方法,当构造器传入对象为null时会抛出异常
public class EventObject implements java.io.Serializable {
@java.io.Serial
private static final long serialVersionUID = 5516075349620653480L;
/**
* The object on which the Event initially occurred.
*/
protected transient Object source;
/**
* Constructs a prototypical Event.
*
* @param source the object on which the Event initially occurred
* @throws IllegalArgumentException if source is null
*/
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
/**
* The object on which the Event initially occurred.
*
* @return the object on which the Event initially occurred
*/
public Object getSource() {
return source;
}
/**
* Returns a String representation of this EventObject.
*
* @return a String representation of this EventObject
*/
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
2.创建EventListener监听器
实现方法一: 创建监听器
ShoppingListener监听器类
注意:实现接口的泛型为自定义事件ShoppingEvent,代表这个监听器监听这个事件
@Component
public class ShoppingListener implements ApplicationListener<ShoppingEvent> {
/**
* 若事件发布则执行该方法
*/
@Override
public void onApplicationEvent(ShoppingEvent event) {
User user = (User) event.getSource();
System.out.println("用户" + user.getId() + "增加积分");
}
}
接口ApplicationListener源码如下,父类EventListener为空接口
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
/**
* Spring框架使用
*/
static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) {
return (event) -> {
consumer.accept(event.getPayload());
};
}
}
实现方法二: @EventListener注解
注意: 注解方式基于反射实现,方法入参为需要监听的事件
@Service
public class SendMsgServiceImpl implements SendMsgService {
/**
* 当用户购买商品则发送消息
*/
@EventListener
public void sendMessagesWhenShopping(ShoppingEvent event) {
User user = (User) event.getSource();
System.out.println("用户" + user.getId() + "成功发送信息");
}
}
3.创建Service发布事件
此处注入ApplicationContext来发布对应事件,SpringBoot会通知对应的监听器去执行对应的事件
@Service
public class ShoppingServiceImpl implements ShoppingService {
@Resource
private ApplicationContext applicationContext;
@Resource
private LoginService loginService;
@Override
public String calcPrice(String price) {
// 获取当前登录用户
User loginUser = loginService.getLoginUser();
// 主要业务 例如创建保存订单等...
// 次要弱依赖业务 此处采用发布事件异步触发增加积分事件
applicationContext.publishEvent(ShoppingEvent.buildEvent(loginUser));
return "success";
}
}
4.创建单元测试
@SpringBootTest
class SpringbootApplicationTests {
@Resource
private ShoppingService shoppingService;
@Test
void contextLoads() {
String result = shoppingService.calcPrice("56");
System.out.println("result = " + result);
}
}
执行单元测试得到结果
用户123增加积分
result = success
至此我们通过SpringBoot实现了观察者模式,其中的通知监听器执行对应事件的操作SpringBoot代我们做了,有兴趣的可以去研究一下对应的源码,本文主打实现,不再过多赘述