概要
- 在项目启动时将所有可能触发的事件处理类注册到spring容器中并使用注解进行标记
- 通过注解获取所有的事件处理类,获取到要触发的方法,将事件和事件处理类存放到map集合进行绑定
- 在进行调用的时候在该map集合中进行查找,并对查询到的事件处理类进行执行
具体实现
public interface IEvent {
}
@Data
public class TestEvent implements IEvent {
public Integer id;
}
public interface EventHandlerI<T>{
default ExecutorService getExecutor() { return null;}
public String execute(T t);
}
@Slf4j
@EventHandler
@Component
public class TestEventHandler implements EventHandlerI<TestEvent> {
@Override
public String execute(TestEvent testEvent) {
log.info("员工id:{}的邮箱申请成功", testEvent.getId());
return null;
}
}
@Component
public class EventHub {
private HashMap<Class, List<EventHandlerI>> eventHandlerRepository = new HashMap<>();
public List<EventHandlerI> getEventHandler(Class<? extends IEvent> eve) {
List<EventHandlerI> handler = findHandler(eve);
if (handler == null || handler.size() == 0){
throw new RuntimeException(eve.getName() + "is not registered in eventHub, please register first");
}
return handler;
}
public void register(Class< ? extends IEvent> event,EventHandlerI eventHandler){
List<EventHandlerI> eventHandlers = eventHandlerRepository.get(event);
if (eventHandlers == null) {
eventHandlers = new ArrayList<>();
eventHandlerRepository.put(event, eventHandlers);
}
eventHandlers.add(eventHandler);
}
public List<EventHandlerI> findHandler(Class<? extends IEvent> eve) {
List<EventHandlerI> eventHandlers = eventHandlerRepository.get(eve);
return eventHandlers;
}
@Component
@Slf4j
public class EventRegister {
@Autowired
private EventHub eventHub;
public Class<? extends IEvent> getEventFromExecutor(Class<?> eventExecutorClz){
Method[] declaredMethods = eventExecutorClz.getDeclaredMethods();
for (Method method : declaredMethods) {
if ("execute".equals(method.getName()) && !method.isBridge()){
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 0){
log.error("execute method should at least have one param");
}
if (!IEvent.class.isAssignableFrom(parameterTypes[0])){
log.error("execute method should the subClass of event ");
}
return (Class)parameterTypes[0];
}
}
throw new RuntimeException("异常");
}
public void doRegisteration(EventHandlerI eventHandlerI){
Class<? extends IEvent> eventClz= getEventFromExecutor(eventHandlerI.getClass());
eventHub.register(eventClz, eventHandlerI);
}
}
@Slf4j
@Component
public class EventBus implements EventBusI {
ExecutorService defaultExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1,
Runtime.getRuntime().availableProcessors() + 1,
0L, TimeUnit.MICROSECONDS,
new LinkedBlockingDeque<>(100));
@Autowired
private EventHub eventHub;
@Override
public void asyncFire(IEvent event) {
eventHub.getEventHandler(event.getClass()).parallelStream().map(p -> {
String res = null;
try {
if (null != p.getExecutor()) {
p.getExecutor().submit(() -> p.execute(event));
} else {
defaultExecutor.submit(() -> p.execute(event));
}
} catch (Exception exception) {
log.error("线程提交执行异常{}暂未实现处理", exception);
}
return "";
}).collect(Collectors.toList());
}
}
public class EventConfig{
@Resource
private EventRegister eventRegister;
public void init() {
ApplicationContext applicationContext = ApplicationContextHelper.getApplicationContext();
Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(EventHandler.class);
beansWithAnnotation.values().stream().forEach(o -> eventRegister.doRegisteration((EventHandlerI) o));
}
}