總結:靈活解耦,業務分離,單一責任,易維護 那么就可以使用觀察模式了,例如:新用戶注冊 會有一系列的贈送活動(積分,優惠券等)。
單體項目 優先推薦guava 的 EventBus 其次spring Event 事件機制,服務分離 就可以考慮 分布式消息隊列。話不多說 代碼入下:
1.spring 事件機制
1.1 定義 事件源
/**
* 事件
* @author lyc
* @date 2019/6/10.
*/
public class UserRegisterEvent extends ApplicationEvent {
public UserRegisterEvent(Object source) {
super(source);
}
}
1.2 定義監聽器
/**
* 監聽器
* @author lyc
* @date 2019/6/10.
*/
@Component
@Slf4j
public class UserRegisterListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
//觸發事件 這里是同步的 異步處理 考慮線程池
if(applicationEvent instanceof UserRegisterEvent) {
log.info("事件觸發");
UserRegisterEvent userRegisterEvent = (UserRegisterEvent) applicationEvent;
User user = (User) userRegisterEvent.getSource();
log.info("原數據{}", user);
//throw new FieldException("================================");
}
}
}
1.3 使用
/發布一個事件
SpringUtils.publishEvent(new UserRegisterEvent(user));
2 EventBus 使用
2.1
定義事件
/**
* @author lyc
* @date 2019/6/10.
*/
public class UserRegisterEvent {
private String message;
public UserRegisterEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
2.2 定義 EventBusService
@Component
public class EventBusService {
// private static EventBus eventBus = new EventBus("user"); //同步
private static AsyncEventBus eventBus = new AsyncEventBus("user", Executors.newFixedThreadPool(10));//異步
/**
* 注冊事件
* @param obj
*/
public static void register(Object obj){
eventBus.register(obj);
}
/**
* 解除注冊
* @param obj
*/
public static void unregister(Object obj){
eventBus.unregister(obj);
}
/**
* 發布事件
* @param obj
*/
public static void post(Object obj){
eventBus.post(obj);
}
}
2.3 定義監聽器 這里我定義了兩個 監聽器 對同一個注冊事件 監聽
@Component
@Slf4j
public class IntegralEventListener {
@Subscribe
public void listen(UserRegisterEvent event){
//送積分
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
log.info("送積分: "+event.getMessage());
}
@Subscribe
public void listen(String message){
log.info("receive message: "+message);
}
}
@Component
@Slf4j
public class CashBackListener {
@Subscribe
public void listen(UserRegisterEvent event){
//送現金
log.info("送現金: "+event.getMessage());
}
@Subscribe
public void listen(String message){
log.info("receive message: "+message);
}
}
2.4 簡單使用
UserRegisterEvent event = new UserRegisterEvent("注冊了");
//注冊一個監聽
eventBusService.register(eventListener);
eventBusService.register(cashBackListener);
//發布一個事件
eventBusService.post(event);
3 rabbitMq 使用
3.1 定義一個隊列
@Configuration
public class RabbitConfig {
@Bean
public Queue registerQueue() {
return new Queue("register");
}
}
3.2 定義一個監聽器
@Component
@Slf4j
public class Receiver {
@RabbitListener(queues = "register")
public void process(String msg) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
log.info("rabbitMq : " + msg);
}
}
3.3 使用 發送到對應隊列
rabbitTemplate.convertAndSend("register","注冊了");