ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。事件发布者并不需要考虑谁去监听,监听具体的实现内容是什么,发布者的工作只是为了发布事件而已。
- 我们平时日常生活中也是经常会有这种情况存在,如:我们在平时拔河比赛中,裁判员给我们吹响了开始的信号,也就是给我们发布了一个开始的事件,而拔河双方人员都在监听着这个事件,一旦事件发布后双方人员就开始往自己方使劲。而裁判并不关心你比赛的过程,只是给你发布事件你执行就可以了。
构建项目
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
创建UserRegister事件
@Getter
public class UserRegister extends ApplicationEvent {
private User user;
/**
* 用户注册事件,重写构造方法
* @param source 发生事件的对象
* @param user 注册用户对象
*/
public UserRegister(Object source,User user) {
super(source);
this.user=user;
}
}
- 这里UserRegister 继承ApplicationEvent 事件,然后根据业务需要重写构造器。构造函数的参数可以任意指定,其中source参数指的是发生事件的对象,一般我们在发布事件时使用的是this关键字代替本类对象,而user参数是我们自定义的注册用户对象,该对象可以在监听内被获取。
- 在Spring内部中有多种方式实现监听如:@EventListener注解、实现ApplicationListener泛型接口、实现SmartApplicationListener接口等,我们下面来讲解下这三种方式分别如何实现。
创建User对象
@Data
public class User {
private String name;
private String passowrd;
}
UserService
public interface UserRegisterService {
String register(User user);
}
@Service
public class UserRegisterServiceImpl implements UserRegisterService {
@Autowired
private ApplicationContext applicationContext;
@Override
public String register(User user) {
if(user.getName()!="" && user.getPassowrd()!="") {
//注册成功!
applicationContext.publishEvent(new UserRegister(this,user));
}
return "注册成功!";
}
}
事件发布是由ApplicationContext对象管控的,我们发布事件前需要注入ApplicationContext对象调用publishEvent方法完成事件发布。
@EventListener实现监听
@Component
@Slf4j
public class AnnotationRegisterListener {
@EventListener
public void register(UserRegister userRegister){
User user = userRegister.getUser();
log.info("@EventListener注册信息,用户名:{},密码:{}",user.getName(),user.getPassowrd());
}
}
测试:
2019-09-16 15:02:10.242 INFO 3188 --- [ main] : @EventListener注册信息,用户名:Lucy,密码:123456
可以看到我们使用@EventListener注解配置的监听已经生效了,当我们在UserService内发布了注册事件时,监听方法自动被调用并且输出内信息到控制台。
ApplicationListener实现监听
@Component
@Slf4j
public class RegisterListener implements ApplicationListener<UserRegister> {
@Override
public void onApplicationEvent(UserRegister userRegister) {
User user = userRegister.getUser();
log.info("@RegisterListener监听 注册信息,用户名:{},密码:{}",user.getName(),user.getPassowrd());
}
}
- 实现ApplicationListener的onApplicationEvent方法来监听事件
测试如下: