黑马程序员技术交流社区

标题: 【成都校区*Spring中的观察者模式】 [打印本页]

作者: 小蜀哥哥    时间: 2019-6-20 21:22
标题: 【成都校区*Spring中的观察者模式】
一、Spring中观察者模式的四个角色
1.事件(ApplicationEvent)
ApplicationEvent 是所有事件对象的父类。ApplicationEvent 继承自 jdk 的 EventObject, 所有的事件都需要继承 ApplicationEvent, 并且通过source得到事件源。
下列描述了Spring提供的内置事件:
2.事件监听(ApplicationListener)
ApplicationListener 事件监听器,也就是观察者。继承自 jdk 的 EventListener,该类中只有一个方法 onApplicationEvent。当监听的事件发生后该方法会被执行。
3.事件发布(ApplicationContext)
ApplicationContext 是 Spring 中的核心容器,在事件监听中 ApplicationContext 可以作为事件的发布者,也就是事件源。因为 ApplicationContext 继承自 ApplicationEventPublisher。在 ApplicationEventPublisher 中定义了事件发布的方法 — publishEvent(Object event)
4.事件管理(ApplicationEventMulticaster)
ApplicationEventMulticaster 用于事件监听器的注册和事件的广播。监听器的注册就是通过它来实现的,它的作用是把 Applicationcontext 发布的 Event 广播给它的监听器列表。
二、Spring中实现观察者模式
@TransactionalEventListener 监听器:如果事件的发布不是在事务(@Transactional)范围内,则监听不到该事件,除非将 fallbackExecution 标志设置为 true(@TransactionalEventListener(fallbackExecution = true));如果在事务中,可以选择在事务的哪个阶段来监听事件,默认在事务提交后监听(@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION))。
以上介绍的事件监听都是同步,如果需要开启异步支持的话:
[AppleScript] 纯文本查看 复制代码
@Configuration
@EnableAsync
public class AsyncEventConfiguration implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        return Executors.newCachedThreadPool();
    }
}
三、 实战
事件(MyEvent.java)
[AppleScript] 纯文本查看 复制代码
@Component
public class MyEvent extends ApplicationEvent {


    public MyEvent(ApplicationContext source) {
        super(source);
        System.out.println("MyEvent 构造器执行");
    }

    public void echo() {
        System.out.println("模拟业务逻辑执行");
    }
}

事件监听(MyListenerA.java、MyListenerB.java)
[AppleScript] 纯文本查看 复制代码
@Component
public class MyListenerA implements ApplicationListener<MyEvent> {


    @Override
    public void onApplicationEvent(MyEvent myEvent) {
        System.out.println("MyListenerA");
        myEvent.echo();
    }
}

[AppleScript] 纯文本查看 复制代码
@Component
public class MyListenerB {
   
    @EventListener
    public void onApplicationEvent(MyEvent myEvent) {
        System.out.println("MyListenerB");
        myEvent.echo();
    }
   
}

事件发布(MyPublisher.java)
[AppleScript] 纯文本查看 复制代码
@Component
public class MyPublisher implements ApplicationContextAware {

    private ApplicationContext applicationContext;


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 发布事件
     * 监听该事件的监听者都可以获取消息
     *
     * @param myEvent
     */
    public void publisherEvent(MyEvent myEvent) {
        System.out.println("---开始发布 myEvent 事件---");
        applicationContext.publishEvent(myEvent);
    }
}

单元测试
[AppleScript] 纯文本查看 复制代码
@RunWith(SpringRunner.class)
@SpringBootTest
public class DesignPatternsApplicationTests {

    @Autowired
    private MyPublisher myPublisher;
    @Autowired
    private MyEvent myEvent;

    @Test
    public void contextLoads() {
        myPublisher.publisherEvent(myEvent);
    }
}







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2