目录
应用场景举例:
观察者模式的优点
观察者模式的缺点
Spring中的观察者模式
代码实现
1、定义事件类型
2、监听者?- 短信
3、监听者?- 邮件
4、发布者 - 发布事件
5、测试发布-监听
应用场景举例:
? ? ? ·?一个事件多个处理方式的场景。
? ·?当用户下单成功后会发送手机短信、邮箱、微信、等。
观察者模式的优点
- 观察者和被观察者之间是抽象耦合,不管是增加观察者还是被观察者都非常容易扩展。
- 建立一套触发机制。
观察者模式的缺点
- 观察者模式需要考虑开发效率和运行效率问题,一个被观察者,多个观察者,开发和调试比较复杂,Java消息的通知默认是顺序执行的,一个观察者卡壳,会影响整体的执行效率。这种情况一般考虑异步的方式。
Spring中的观察者模式
ApplicationContext中事件处理是由ApplicationEvent类和ApplicationListener接口来提供的。如果一个Bean实现了ApplicationListener接口,并且已经发布到容器中去,每次ApplicationContext发布一个ApplicationEvent事件,这个Bean就会接到通知。Spring事件机制是观察者模式的实现。
Spring中的事件机制涉及到者几个类文件 :
? ?ApplicationListener 监听者(事件监听)接口
? ?ApplicationEventPublisherAware 发布者(事件发布类)接口
? ?ApplicationEvent?事件类型(定义事件的数据结构)类
代码实现

1、定义事件类型
就是定义事件的数据结构。
/**
* 定义事件类型(定义事件的数据结构)
*/
public class UserRegisterEvent extends ApplicationEvent {
/** 用户名 */
private String username;
public UserRegisterEvent(Object source) {
super(source);
}
public UserRegisterEvent(Object source, String username) {
super(source);
this.username = username;
}
public String getUsername() {
return username;
}
}
2、监听者?- 短信
/**
* 监听者 - 短信监听(异步执行)
*/
@Component
public class SmsListener implements ApplicationListener<UserRegisterEvent> {
@Override
@Async //异步
public void onApplicationEvent(UserRegisterEvent event) {
System.out.println(Thread.currentThread() + ",短信监听到>>>" + event.getUsername()+ "," + event.getSource());
}
}
3、监听者?- 邮件
@Component
public class EmailListener implements ApplicationListener<OrderEvent> {
private static final Logger logger = Logger.getLogger(EmailListener.class);
@Override
@Async
public void onApplicationEvent(OrderEvent event) {
System.out.println(Thread.currentThread() + ",邮件监听到>>>" + event.getMessage()+ "," + event.getSource());
}
}
4、发布者 - 发布事件
/**
* 发布者
*/
@Service
public class UserServicePublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
/**
* 发布
*/
public void register(String username) {
System.out.println("发布 >>>>>> "+ username);
applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username));
}
}
最后在启动类上加上开启异步注解 @EnableAsync,否则监听者将会串行执行。
5、测试发布-监听
@RestController
public class TestController {
@Autowired
private UserServicePublisher userService;
@RequestMapping("/test/register")
public void testRegister(){
userService.register("王明");
}
}
请求:http://127.0.0.1:8080/test/register
然后查看控制台打印:
?
|