Spring事件通知
1.编写自定义的事件载体对象
/**
* @Author:qmfang
* @Description: 继承自事件对象,表明将其作为一个事件通知对象
* @Date:Created in 10:35 2018/4/8
* @Modified By:
*/
@Data
public class BlackListEvent extends ApplicationEvent {
private final String address;
private final String test;
public BlackListEvent(Object source, String address, String test) {
super(source);
this.address = address;
this.test = test;
}
}
2.编写事件触发对象
/**
* @Author:qmfang
* @Description: 实现以aware结尾的接口之后在bean被实例化之后会Spring会注入相应的资源
* @Date:Created in 10:37 2018/4/8
* @Modified By:
*/
public class EmailService implements ApplicationEventPublisherAware {
private List<String> blackList;
private ApplicationEventPublisher publisher;
public void setBlackList(List<String> blackList) {
this.blackList = blackList;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
/**
* 此处也就是注册进入应用事件发布对象
*/
this.publisher = applicationEventPublisher;
}
public void sendEmail(String address, String test) {
if (blackList.contains(address)) {
/**
* 如果是包含的地址将发布该消息
*/
BlackListEvent event = new BlackListEvent(this, address, test);
publisher.publishEvent(event);
return;
}
}
}
3.编写相应的事件监听对象
/**
* @Author:qmfang
* @Description: 实现ApplicationListener的接口将监听相应的事件,当有事件时,将触发onApplicationEvent方法
* @Date:Created in 10:44 2018/4/8
* @Modified By:
*/
public class BlackListNotifier implements ApplicationListener<BlackListEvent> {
@Override
public void onApplicationEvent(BlackListEvent event) {
System.out.println("应用事件:" + event);
}
}
4.将相应的对象注入到容器
/**
* @Author:qmfang
* @Description:
* @Date:Created in 9:58 2018/4/8
* @Modified By:
*/
@Configuration
public class MvcConfig {
@Bean
public EmailService emailService() {
EmailService emailService = new EmailService();
List list = Arrays.asList("known.spammer@example.org", "known.hacker@example.org", "john.deo@example.org");
emailService.setBlackList(list);
return emailService;
}
@Bean
public BlackListNotifier blackListNotifier() {
BlackListNotifier blackListNotifier = new BlackListNotifier();
return blackListNotifier;
}
}
4.编写测试
@RestController
public class TestController {
@Autowired
private EmailService emailService;
/**
* 127.0.0.1:8886/test
*
* @return
*/
@GetMapping("/test")
public Object get() {
emailService.sendEmail("known.spammer@example.org", "test@test");
return "hello";
}
}
基于注解的事件处理
基于注解的可以将BlackListNotifier修改为如下形式
/**
* @Author:qmfang
* @Description: 实现ApplicationListener的接口将监听相应的事件,当有事件时,将触发onApplicationEvent方法
* @Date:Created in 10:44 2018/4/8
* @Modified By:
*/
public class BlackListNotifier {
/**
* 也可以基于注解的形式 参数表名了需要监听的事件类型
*
* @param event
*/
@EventListener
public void onApplicationEvent(BlackListEvent event) {
System.out.println("应用事件:" + event);
}
/**
* 如果方法需要监听好几个事件,或者如果定义的方法没有任何参数,也可以在注解自身上指定事件类型
*/
@EventListener({ContextStartedEvent.class, ContextRefreshedEvent.class})
public void handleContextStart() {
System.out.println("监听到事件");
}
/**
* 也可以通过定义SpEL表达式的注解condition属性添加额外的运行时过滤,
* 他们应该匹配以实际调用特定事件的方法,例如如果事件的test属性等于foo
* 才回调该方法
* <p>
* SpEL可用的元数据
* 名字 位置 描述 例子
* Event事件 根对象 实际应用事件 #root.event
* Arguments array参数数组 根对象 用于目标数组 #root.args[0]
* Argumentname参数名称 评估上下文 任意方法参数的名字
*/
@EventListener(condition = "#event.test=='foo'")
public void onApplicationEvent2(BlackListEvent event) {
System.out.println("应用事件2:" + event);
}
/**
* 如果需要发布一个事件作为另一个事件的结果,只需要更改方法签名返回应该发布的事件即可
* 注意点是:异步事件不支持此功能
*/
@EventListener
public OtherEvent handlerBlackListEvent(BlackListEvent event) {
}
}