Java中使用Google MapBinder实现单个EventType绑定多个EventListener的方法
正确实现方案
Guice 原生提供了Multibinder组件用于处理单个类型绑定多个实现的场景,和MapBinder搭配即可实现单个EventType绑定多个EventListener的需求,具体配置如下:
绑定代码
import com.google.inject.TypeLiteral; import com.google.inject.name.Names; import com.google.inject.multibindings.MapBinder; import com.google.inject.multibindings.Multibinder; // 1. 定义泛型正确的MapBinder,值类型为EventListener的Set集合 MapBinder<EventType, Set<EventListener>> eventListenerMapBinder = MapBinder.newMapBinder(binder(), EventType.class, new TypeLiteral<Set<EventListener>>() {}); // 2. 为DUMMY_EVENT创建专属的Multibinder,用事件名做命名注解避免不同事件的监听器集合冲突 Multibinder<EventListener> dummyEventListeners = Multibinder.newSetBinder( binder(), EventListener.class, Names.named(EventType.DUMMY_EVENT.name()) ); // 绑定该事件对应的多个监听器实现 dummyEventListeners.addBinding().to(DummyListener.class); dummyEventListeners.addBinding().to(AnotherDummyListener.class); // 3. 将事件类型和对应的监听器Set绑定 eventListenerMapBinder .addBinding(EventType.DUMMY_EVENT) .to(Key.get(new TypeLiteral<Set<EventListener>>() {}, Names.named(EventType.DUMMY_EVENT.name())));
注入使用
配置完成后可以直接在EventRegistry等组件中注入两种类型的Map:
- 懒加载模式:注入
Map<EventType, Provider<Set<EventListener>>>,只有用到对应事件的监听器时才会实例化 - 即时加载模式:注入
Map<EventType, Set<EventListener>>,启动时就会实例化所有监听器
原写法失效原因
你之前的写法存在两个核心问题:
- Guice的
to()方法仅支持绑定Key或者Class类型,不能直接传入Arrays.asList生成的实例对象 - 使用原生
List作为值类型存在泛型擦除问题,Guice无法正确管理List内部元素的依赖注入和生命周期
内容的提问来源于stack exchange,提问作者Pradipta Sarma
相关产品推荐
相关产品推荐

