Java设计模式之观察者模式再温习

10 篇文章 0 订阅

观察者模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并完成处理。观察者模式的应用场景是优化执行流程,将非核心流程由串行执行改为异步执行,如下单成功后发送消息。

观察者模式的核心类:

  • Observerable:被观察者,核心方法:添加观察者、移除观察者、通知观察者
  • Observer:观察者接口
  • ObserverImp:观察者实现

实例

public interface Observer {
    /**
     * 观察者事件
     */
    void doEvent();
}
public class EmailObserver implements Observer {
    @Override
    public void doEvent() {
        System.out.println("发送email消息");
    }
}
public class MobileNoObserver implements Observer {
    @Override
    public void doEvent() {
        System.out.println("发送短信消息");
    }
}
public class Observerable {

    private List<Observer> observers = new ArrayList<>();

    /**
     * 添加观察者
     */
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    /**
     * 移除观察者
     */
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    /**
     * 通知
     * @return
     */
    public void notifyAllObserver(int state) {
        if (state != 1) {
            System.out.println("非通知状态");
            return;
        }
        for (Observer observer : observers) {
            observer.doEvent();
        }
    }

}
		// 创建订单成功,返回状态
        int insert = 1;
        // 创建被观察者
        Observerable observerable = new Observerable();
        // 添加观察者
        observerable.addObserver(new EmailObserver());
        // 添加观察者
        observerable.addObserver(new MobileNoObserver());
        // 通知观察者
        observerable.notifyAllObserver(insert);
        System.out.println("下单成功");

在spring框架中,也有观察者模式的应用,Spring ApplicationEvent事件。
事件机制在一些大型项目中被经常使用,Spring ApplicationEvent就是Spring专门提供的一套事件机制的接口,满足了架构原则上的解耦。
ApplicationContext 通过 ApplicationEvent 类和 ApplicationListener 接口进行事件处理。如果将实现 ApplicationListener 接口的 bean 注入到上下文中,则每次使用 ApplicationContext 发布 ApplicationEvent 时,都会通知该实现 ApplicationListener 接口的 bean。ApplicationEvent 是由 Spring 提供的所有 Event 类的基类。
实例
自定义业务事件子类,继承 ApplicationEvent,通过泛型注入业务模型参数类

public class AbstractGenericEvent<T> extends ApplicationEvent {

    public AbstractGenericEvent(Object source) {
        super(source);
    }

    public AbstractGenericEvent(Object source, Clock clock) {
        super(source, clock);
    }
}

事件实现类

public class OrderEvent extends AbstractGenericEvent<OrderModel> {

    public OrderEvent(OrderModel source) {
        super(source);
    }
}

事件监听器类,实现ApplicationListener 接口

@Component
public class OrderEventListener implements ApplicationListener<OrderEvent> {

    @Override
    public void onApplicationEvent(OrderEvent event) {
        //
        System.out.println(Thread.currentThread().getName() + "-receive msg: " + JSON.toJSONString(event.getSource()));

    }
}
@Component
public class EmailEventListener implements ApplicationListener<OrderEvent> {

    @Override
    public void onApplicationEvent(OrderEvent event) {
        //
        System.out.println(Thread.currentThread().getName() + "-send email: " + JSON.toJSONString(event.getSource()));

    }
}

测试

	@GetMapping("hello")
    public Object hello() {
        OrderModel orderModel = new OrderModel();
        orderModel.setId("1");
        orderModel.setName("caocao");
        // 发布Spring事件通知
        SpringBeanUtil.getApplicationContext().publishEvent(new OrderEvent(orderModel));
        System.out.println(Thread.currentThread().getName() + "-publish: ");
        return "hello";
    }

结果如下
在这里插入图片描述
从结果发现,无论是发布事件,还是监听事件使用了同一个线程,spring框架的事件机制默认是同步堵塞的,要想实现异步调用,需手动创建一个配置类,并设置线程池,如下

@Component
public class SpringConfiguration {

    @Bean
    public SimpleApplicationEventMulticaster applicationEventMulticaster(@Qualifier("defaultThreadPoolExecutor") ThreadPoolExecutor defaultThreadPoolExecutor) {
        SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster();
        simpleApplicationEventMulticaster.setTaskExecutor(defaultThreadPoolExecutor);
        return simpleApplicationEventMulticaster;
    }

}

结果如下
在这里插入图片描述
从结果发现,发布和监听由不同的线程执行。
那SimpleApplicationEventMulticaster 实例化和系统默认的实例化加载顺序如如何?
在spring源码中,处理逻辑在 AbstractApplicationContext的initApplicationEventMulticaster 方法中,通过 beanFactory 查找是否有自定义的 Bean,如果没有,容器会自己 new 一个 SimpleApplicationEventMulticaster 对象注入到容器中。
在这里插入图片描述
还需继续分析spring中应用的设计模式及底层原理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值