发布订阅模型, 事件机制

 

1.背景

在系统中某人保存文章之后,需要将这个消息通知给他的好友。如果直接把代码写在文章业务代码中则耦合太高,后续如果还有其他操作也写在一起,那么代码会越来越复杂难以维护。而采用发布订阅模式可以很好地进行解耦。

 2.流程

    1) EventListener初始化时候主动通过EventRegister向EventDispatcher注册,提供要订阅的事件类型。(或直接在EventDispatcher中提供注册方法)

    2) EventPublisher在事件发生时,向EventDispatcher提交事件

     3) EventDispatcher根据提交的事件类型,获取订阅该事件类型的订阅者,并向他们发送事件

 

3. 主要代码:

  Event

public class Event extends EventObject{

	public Event(Object source) {
		super(source);
	}
	
	private EventType eventType;

	public EventType getEventType() {
		return eventType;
	}

	public void setEventType(EventType eventType) {
		this.eventType = eventType;
	}
	
	public Map<String, Object> params;

	public Map<String, Object> getParams() {
		return params;
	}

	public void setParams(Map<String, Object> params) {
		this.params = params;
	}
	
	private EventAction eventAction;

	public EventAction getEventAction() {
		return eventAction;
	}

	public void setEventAction(EventAction eventAction) {
		this.eventAction = eventAction;
	}
	
}

 

EventPublisher

public interface EventPublisher {
	public void publish(Event event);
}

DefaultPublisher

@Component
public class DefaultPublisher implements EventPublisher{
	
	@Override
	public void publish(Event event) {
		EventDispatcher.getInstance().postEvent(event);
	}

}

EventListener

public interface EventListener {
	
	public void change(Event event);
	
	public boolean canAccept(Event event);
	
}

InfoEventListener

@Component
public class InfoEventListener implements EventListener {
	@Autowired
	private EventRegister register;
	
	@PostConstruct
	public void init() {
		register.regist(this, EventType.InfoEvent);
	}
	
	@Override
	public boolean canAccept(Event event) {
		return event.getEventType().equals(EventType.InfoEvent);
	}

	@Override
	public void change(Event event) {
		System.out.println("InfoEventListener 接收到change事件 " + event.getSource().toString());
		InfoEvent infoEvent = (InfoEvent)event;
		switch (infoEvent.getEventAction()) {
		case save:
			onInfoSave(infoEvent);
			break;
		default:
			break;
		}
		
		
	}
	
	public void onInfoSave(InfoEvent event) {
		System.out.println("InfoEventListener 接收到onInfoSave事件 " + event.getName());
	}

}

EventDispatcher

public class EventDispatcher {
	
	private static volatile EventDispatcher instance = null;
	
	public static EventDispatcher getInstance() {
		if(instance == null) {
			synchronized(EventDispatcher.class) {
				if(instance == null) {
					instance = new EventDispatcher();
				}
			}
		}
		return instance;
	}
	
	public EventDispatcher() {
		this.eventListeners = new HashMap<>();
	}
	
	
	private Map<String, List<EventListener>> eventListeners;

	public Map<String, List<EventListener>> getEventListeners() {
		return eventListeners;
	}

	public void setEventListeners(Map<String, List<EventListener>> eventListeners) {
		this.eventListeners = eventListeners;
	}
	
	public List<EventListener> getEventListenerByType(String eventType){
		List<EventListener> listeners = eventListeners.get(eventType);
		if(listeners==null||listeners.isEmpty()) {
			listeners = new ArrayList<>();
			this.eventListeners.put(eventType, listeners);
		}
		return listeners;
	}
	
	public void addEventListener(String eventType, EventListener eventListener) {
		List<EventListener> listeners = getEventListenerByType(eventType);
		listeners.add(eventListener);
	}
	
	//TODO 增加removeEventListener
	
	public void postEvent(Event event) {
		List<EventListener> listeners = eventListeners.get(event.getEventType().getValue());
		if(!listeners.isEmpty()) {
			for(EventListener listener : listeners) {
				if(listener.canAccept(event)) {
					listener.change(event);
				}
			}
		}
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值