三种方式实现观察者模式 及 Spring中的事件编程模型 (3)

当时学习Spring,看到Spring提供了各式各样的接口来让程序员们对Spring进行扩展,并且没有任何侵入性,我不得不佩服Spring的开发者们。这里也是,我们可以看到在客户端找不到任何关于“订阅事件”的影子。

这种实现方式不是太好,可以看到我们在方法内部做了一个判断:接收到的事件是否为ContextRefreshedEvent。

伟大的Spring还提供了泛型的ApplicationListener,我们可以通过泛型的ApplicationListener来完善上面的代码:

@Component public class MyListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("刷新了"); } }

我们还可以利用Spring中的事件编程模型来自定义事件,并且发布事件:

首先,我们需要定义一个事件,来实现ApplicationEvent接口,代表这是一个Application事件,其实上面所说的四个内置的事件也实现了ApplicationEvent接口:

public class MyEvent extends ApplicationEvent { public MyEvent(Object source) { super(source); } }

还需要定义一个监听器,当然,在这里需要监听MyEvent事件:

@Component public class MyListener implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent event) { System.out.println("我订阅的事件已经到达"); } }

现在有了事件,也有了监听器,是不是还少了发布者,不然谁去发布事件呢?

@Component public class MyEventPublish implements ApplicationEventPublisherAware { private ApplicationEventPublisher publisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } public void publish(Object obj) { this.publisher.publishEvent(obj); } }

发布者,需要实现ApplicationEventPublisherAware 接口,重写publish方法,顾名思义,这就是发布方法,那么方法的参数obj是干嘛的呢,作为发布者,应该需要知道我要发布什么事件,以及事件来源(是谁触发的)把,这个obj就是用来存放这样的数据的,当然,这个参数需要我们手动传入进去。setApplicationEventPublisher是Spring内部主动调用的,可以简单的理解为初始化发布者。

现在就剩最后一个角色了,监听器有了,发布者有了,事件也有了,对,没错,还少一个触发者,毕竟要有触发者去触发事件啊:

@Component public class Service { @Autowired private MyEventPublish publish; public void publish() { publish.publish(new MyEvent(this)); } }

其中publish方法就是给客户端调用的,用来触发事件,可以很清楚的看到传入了new MyEvent(this),这样发布者就可以知道我要触发什么事件和是谁触发了事件。

当然,还需要把一切交给Spring管理:

@Configuration @ComponentScan public class AppConfig { }

客户端:

public static void main(String[] args) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(AppConfig.class); context.getBean(Service.class).publish();; }

运行结果:

这一篇博客比较简单,只是简单的应用,但是只有会了应用,才能谈源码。

这篇博客到这里就结束了,谢谢大家。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyxpzp.html