spring中的applicationEvent和applicationListener使用
ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。
事件发布者并不需要考虑谁去监听,监听具体的实现内容是什么,发布者的工作只是为了发布事件而已。
通过 ApplicationEvent 类和 ApplicationListener 接口来提供在 ApplicationContext 中处理事件。如果一个 bean 实现 ApplicationListener,那么每次 ApplicationEvent 被发布到 ApplicationContext 上,那个 bean 会被通知。
Spring 内置事件 & 描述 | |
---|---|
1 | ContextRefreshedEvent ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext 接口中使用 refresh() 方法来发生。 |
2 | ContextStartedEvent当使用 ConfigurableApplicationContext 接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。 |
3 | ContextStoppedEvent当使用 ConfigurableApplicationContext 接口中的 stop() 方法停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。 |
4 | ContextClosedEvent当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。 |
5 | RequestHandledEvent这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。 |
测试思路
添加用户,当用户不存在时,正常添加用户,当用户存在时触发监听器…
创建event事件
继承applicationEvent即可
/**
* 这是创建了一个事件,当使用此事件时,会根据条件触发监听器
*/
@Data
public class UserEvent extends ApplicationEvent {
private String name;
public UserEvent(Object source, String name) {
super(source);
this.name = name;
}
}
创建监听器
使用注解的方式创建,简单灵活.监听器可以创建多个,使用@Order(1)标注执行顺序,使用@Async执行异步的处理(启动类开始异步).
/**
* 这是一个事件的监听器,当监听到事件的时候回执行方法.
*/
@Component
public class UserAddListener {
@Async
@EventListener
@Order(1)
public void listener1(UserEvent userEvent) {
System.out.println(Thread.currentThread().getName()+ userEvent.getName()+"已经存在了1111");
}
@Async
@EventListener
@Order(2)
public void listener2(UserEvent userEvent) {
System.out.println(Thread.currentThread().getName()+ userEvent.getName()+"已经存在了22222");
}
}
创建发布器
主要的业务逻辑都在这里,这里是我们调用触发监听器方法的地方.
/**
* 这是一个事件发布器,这里有具体的监听的事件的方法.例如addUser()
*/
@Service
public class UserService {
//已经存在的用户名,出现重复则触发listener
private List<String> userList=new ArrayList<>(Arrays.asList("zs","ls","ww","zl"));
public void setUserList(List<String> userList) {
this.userList = userList;
}
@Autowired
private ApplicationContext context;
public void addUser(String name) {
UserEvent event = new UserEvent(context, name);
for (String str : userList) {
//当用户存在时,触发
if (str.equals(event.getName())) {
context.publishEvent(event);
}
}
}
}
简单的测试
@RestController
public class ListenerController {
@Autowired
private UserService userService;
@RequestMapping("/test01")
public void test01() {
userService.addUser("qq");
System.out.println(Thread.currentThread().getName()+"qq在list中不存在,不会触发listener");
}
@RequestMapping("/test02")
public void test02() {
userService.addUser("zs");
System.out.println(Thread.currentThread().getName()+"zs在list中已经存在,会触发listener");
}
}
结果
当触发test01时不会触发监听器,因为qq不存在列表中.
当触发test02时会触发监听器.