基于guava整合spring实现EventBus

基于guava整合spring实现EventBus

为什么要用EventBus?

实现了进程内广播与监听,代码层实现了逻辑解耦。通常用于发短信、邮件、写日志、数据埋点等场景。

为什么要整合spring重新造轮子?

原因是直接使用EventBus监听的类是不被spring托管,也就是说 @Subscribe类是不能直接通过spring 注入bean。

下面将讲解下我的实现:

/***
 ** 用于标记Event事件
 **/
public interface BaseEvent {

}
/***
 ** 所有Event处理类都要继承此Adapter类 实现process进行相关event处理
 **/
public abstract class EventAdapter<E extends BaseEvent> {

    private static final Logger logger = LoggerFactory.getLogger(EventAdapter.class);

    private static final String METHOD_NAME = "process";

    @Subscribe
    @SuppressWarnings("all")
    public void onEvent(BaseEvent event) {
    if (ReflectionUtils.findMethod(this.getClass(), METHOD_NAME, event.getClass()) != null) {
        try {
        if (!process((E)event)) {
            logger.warn("handle event {} fail", event.getClass());
        }
        } catch (Exception e) {
        logger.error(String.format("handle event %s exception", event.getClass()), e);
        }
    }
    }

    public abstract boolean process(E e);

}
/***
 ** EventBus处理类,主要用于注册或注销及发布相关事件
 */
public class EventBusFacade {
    
    private static final Logger logger = LoggerFactory.getLogger(EventBusFacade.class);
    
    private final static EventBus eventBus = new EventBus();
    
    public static void post(BaseEvent event) {
	   execute(event);
    }
    

    public static void execute(BaseEvent event) {
	   if(event == null){
	       return ;
	   }
	   eventBus.post(event);
    }
    
    
    
    public static void register(EventAdapter<? extends BaseEvent> handler) {
	   if(handler == null){
	      return ;
	   }
	   eventBus.register(handler);
	   logger.info("Registered eventAdapter class: {}", handler.getClass());
    }

    
    public static void unregister(EventAdapter<? extends BaseEvent> handler) {
	   if(handler == null){
	       return ;
	   }
	   eventBus.unregister(handler);
	   logger.info("Unregisted eventAdapter class: {}", handler.getClass());
    }

}

三个类就完成核心的封装,下面通过什么办法可以实现自动注册及注销EventAdapter呢,请继续往下看:

@Configuration
@SuppressWarnings("all")
public class EventBusConfiguration implements InitializingBean, DisposableBean {

    @Autowired
    private ApplicationContext applicationContext;

    private Map<String, EventAdapter> beans = null;

    @Override
    public void afterPropertiesSet() throws Exception {

	   beans = applicationContext.getBeansOfType(EventAdapter.class);
	   if (beans != null) {
	      for (EventAdapter eventAbstract : beans.values()) {
		     EventBusFacade.register(eventAbstract);
	      }
	   }
    }

    @Override
    public void destroy() throws Exception {
	   if (beans != null) {
	       for (EventAdapter eventAbstract : beans.values()) {
		      EventBusFacade.unregister(eventAbstract);
	       }
	   }
    }

}

OK,到这就已实现自动注册及注销 EventAdapter ,再加上下面这个激活注解就完美了。

@Configuration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(EventBusConfiguration.class)
@Documented
public @interface EnableEventBus {
    
}

到此,封装结束;

使用示例:

public class TestEvent implements BaseEvent{
    
    private String name;
    
    public TestEvent(){}
    
    public TestEvent(String a){
	this.name = a;
    }
    
    public String getName() {
        return name;
    }

    
    public void setName(String name) {
        this.name = name;
    }
    
}



@Component
public class TestEventHandler extends EventAdapter<TestEvent>{
    
    private static final Logger logger = LoggerFactory.getLogger(EventBusFacade.class);
    
    @Override
    public boolean process(TestEvent e) {
	
	  logger.info("==================== 收到测试事件 ===================");
	
	  return true;
    }

}


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/spring.xml")
public class TestLaunch {

    @Test
    public void testExecute() {

	   EventBusFacade.execute(new TestEvent()); //发布事件

    }
    
}

转载至链接:https://my.oschina.net/woter/blog/1839830

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值