观察者模式:Spring 事件机制基于观察者模式,可以让不同的组件之间解耦合,实现了松耦合。
@Component
public class MyEventPublisher {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void publishEvent() {
MyEvent event = new MyEvent(this);
eventPublisher.publishEvent(event);
}
}
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
// do something
}
}
public class MyEvent extends ApplicationEvent {
public MyEvent(Object source) {
super(source);
}
}
在上述代码中,MyEventPublisher 发布了一个 MyEvent 事件,MyEventListener 监听 MyEvent 事件,当 MyEvent 事件被触发时,MyEventListener 的 onApplicationEvent 方法将被调用。
在 Spring 中,观察者模式主要应用在事件机制中。Spring 的事件机制是基于观察者模式实现的,其中事件源(Publisher)和事件监听器(Listener)分别对应着观察者模式中的 Subject 和 Observer。当事件源发生事件时,会通知所有的事件监听器,并触发相应的事件处理方法。
我们再来看一个使用观察者模式的示例代码:
@Component
public class UserService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void register(User user) {
// 注册用户
...
// 发送注册成功事件
eventPublisher.publishEvent(new UserRegisteredEvent(user));
}
}
@Component
public class UserRegisteredEventListener implements ApplicationListener<UserRegisteredEvent> {
@Override
public void onApplicationEvent(UserRegisteredEvent event) {
// 处理注册成功事件
...
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
User user = new User("Alice", "123456");
userService.register(user);
}
在上面的代码中,UserService 发布了一个 UserRegisteredEvent 事件,并由 UserRegisteredEventListener 来处理该事件。在 main 方法中,我们从容器中获取了 UserService 实例,并调用了 register 方法来触发事件的发布。当事件被发布时,Spring 会自动调用所有注册了 UserRegisteredEvent 事件监听器的 onApplicationEvent 方法来处理事件。
在 Spring 中,事件机制是通过 ApplicationEventPublisher 接口和 ApplicationListener 接口实现的。当事件源发布事件时,会调用 ApplicationEventPublisher 接口的 publishEvent 方法来通知所有的事件监听器。而事件监听器需要实现 ApplicationListener 接口,并指定要监听的事件类型。当事件发生时,Spring 会自动调用相应事件监听器的 onApplicationEvent 方法来处理事件。
在实现上,Spring 使用了 ConcurrentMap 来存储事件监听器。当一个新的事件监听器被注册时,Spring 会将其添加到相应的事件类型的监听器列表中。而当事件源发布事件时,Spring 会根据事件类型来查找相应的事件监听器,并调用其 onApplicationEvent 方法来处理事件。由于 ConcurrentMap 的线程安全性,Spring 的事件机制是线程安全的,可以在多线程环境下使用。