一、Spring boot 事件机制的简单例子
本例模拟一个人向多个人传递内容,人与人之间的消息分享。
1.定义事件
Java代码
package com.fund.fundmodel.interview.event;
import lombok.Data;
import org.springframework.context.ApplicationEvent;
@Data
public class MyContentEvent extends ApplicationEvent{
private String content;
public MyContentEvent(Object source,String content) {
super(source);
this.content = content;
}
}
如果用户发送内容,只需要通过构造器传入内容,然后通过getSource即可获取。
2.定义无序监听器
顺序无法确定,类似于AOP机制
1).不指定事件类型的实现方式
1.使用@Compoent注册Bean即可;
2.在实现中需要判断event类型是ContentEvent才可以处理;
3.通过注解@Async可实现异步
Java代码:
package com.fund.fundmodel.interview.listener;
import com.fund.fundmodel.interview.event.MyContentEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 无序监听器 异步
* 不指定事件类型的实现方式
*/
@Component
public class ParentListener implements ApplicationListener<ApplicationEvent> {
@Async
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
if(applicationEvent instanceof MyContentEvent){
System.out.println(" 跟 父母 分享了有趣的内容:"+((MyContentEvent) applicationEvent).getContent()+" **** :"+applicationEvent.getSource());
}
}
}
2).指定事件类型 (通过泛型制定事件类型)
Java代码:
package com.fund.fundmodel.interview.listener;
import com.fund.fundmodel.interview.event.MyContentEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 无序监听器 异步
* 通过泛型指定类型
*/
@Component
public class BrotherListener implements ApplicationListener<MyContentEvent> {
@Async
@Override
public void onApplicationEvent(MyContentEvent myContentEvent) {
System.out.println(" 跟 兄弟 分享了有趣的内容:"+myContentEvent.getContent()+" **** :"+myContentEvent.getSource());
}
}
3.定义有序监听器
1).supportsEventType:用于指定支持的事件类型,只有支持的才调用onApplicationEvent;
2).supportsSourceType:支持的目标类型,只有支持的才调用onApplicationEvent;
3).getOrder:即顺序,越小优先级越高
同事1 Java代码:
package com.fund.fundmodel.interview.listener;
import com.fund.fundmodel.interview.event.MyContentEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
@Component
public class Colleague1Listener implements SmartApplicationListener {
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) {
return aClass == MyContentEvent.class;
}
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return sourceType == String.class;
}
@Override
public int getOrder() {
return 1;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
System.out.println("同事1 在 同事2 之前 收到我分享的有趣的内容:"+((MyContentEvent) applicationEvent).getContent()+" **** :"+applicationEvent.getSource());
}
}
同事2 Java代码:
package com.fund.fundmodel.interview.listener;
import com.fund.fundmodel.interview.event.MyContentEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
@Component
public class Colleague2Listener implements SmartApplicationListener {
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) {
return aClass == MyContentEvent.class;
}
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return sourceType == String.class;
}
@Override
public int getOrder() {
return 2;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
System.out.println("同事2 在 同事1 之后 收到我分享的有趣的内容:"+((MyContentEvent) applicationEvent).getContent()+" **** :"+applicationEvent.getSource());
}
}
4.异步支持
spring3提供了@Aync注解来完成异步调用。此时我们可以使用这个新特性来完成异步调用。
5.测试
测试类代码:
package com.fund.fundmodel.interview;
import com.fund.fundmodel.interview.event.MyContentEvent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyContentEventTest {
@Autowired
private ApplicationContext applicationContext;
@Test
public void testPublishEvent() {
applicationContext.publishEvent(new MyContentEvent("宝宝会说话了!","她会喊爸爸了!"));
}
}
结果输出:
同事1 在 同事2 之前 收到我分享的有趣的内容:她会喊爸爸了! **** :宝宝会说话了!
同事2 在 同事1 之后 收到我分享的有趣的内容:她会喊爸爸了! **** :宝宝会说话了!
跟 父母 分享了有趣的内容:她会喊爸爸了! **** :宝宝会说话了!
跟 兄弟 分享了有趣的内容:她会喊爸爸了! **** :宝宝会说话了!
到此spring boot中构建事件机制的简单实例已完成,更多原理说明后续更新。