如何通过Lombok与Guice为不同调用类注入命名Provider?
解决方案
要实现为CallerA和CallerB分别注入绑定不同Client的Strategy,你可以通过Guice的命名绑定配合Lombok构造器注解来实现,具体步骤如下:
1. 调整Strategy类(不硬编码Client绑定)
不需要在Strategy的Client字段上固定命名注解,让Guice通过模块配置控制注入的Client实例:
@RequiredArgsConstructor(onConstructor = @__(@Inject)) class Strategy { private final Client client; public void runMe() { // 原有业务逻辑 client.doThings(); } }
2. 完善Guice模块配置
在模块中新增两个命名的Strategy提供者,分别关联对应的Client实例:
public class ClientModule extends AbstractModule { @Override protected void configure() {} // 提供ClientA实例 @Provides @Named("ClientA") public Client providesClientA() { return ClientA.builder().build(); } // 提供ClientB实例 @Provides @Named("ClientB") public Client providesClientB() { return new ClientB(); // 替换为你的ClientB构造逻辑 } // 绑定使用ClientA的Strategy实例 @Provides @Named("StrategyWithClientA") public Strategy providesStrategyWithClientA(@Named("ClientA") Client client) { return new Strategy(client); } // 绑定使用ClientB的Strategy实例 @Provides @Named("StrategyWithClientB") public Strategy providesStrategyWithClientB(@Named("ClientB") Client client) { return new Strategy(client); } }
3. 修改Caller类,注入对应命名的Strategy
CallerA(使用ClientA的Strategy)
@RequiredArgsConstructor(onConstructor = @__(@Inject)) class CallerA { @Named("StrategyWithClientA") private final Strategy strategy; public void run() { strategy.runMe(); } }
CallerB(使用ClientB的Strategy)
@RequiredArgsConstructor(onConstructor = @__(@Inject)) class CallerB { @Named("StrategyWithClientB") private final Strategy strategy; public void run() { strategy.runMe(); } }
可选优化:用自定义绑定注解替代@Named
如果想避免字符串魔法值,可创建自定义绑定注解让代码更健壮:
- 创建两个自定义注解:
@BindingAnnotation @Target({FIELD, PARAMETER, METHOD}) @Retention(RUNTIME) public @interface ForClientA {}
@BindingAnnotation @Target({FIELD, PARAMETER, METHOD}) @Retention(RUNTIME) public @interface ForClientB {}
- 调整模块中的提供者注解:
@Provides @ForClientA public Client providesClientA() { return ClientA.builder().build(); } @Provides @ForClientB public Client providesClientB() { return new ClientB(); } @Provides @ForClientA public Strategy providesStrategyForClientA(@ForClientA Client client) { return new Strategy(client); } @Provides @ForClientB public Strategy providesStrategyForClientB(@ForClientB Client client) { return new Strategy(client); }
- 修改Caller类的字段注解:
// CallerA @RequiredArgsConstructor(onConstructor = @__(@Inject)) class CallerA { @ForClientA private final Strategy strategy; // ... } // CallerB @RequiredArgsConstructor(onConstructor = @__(@Inject)) class CallerB { @ForClientB private final Strategy strategy; // ... }
内容的提问来源于stack exchange,提问作者ikmckenz
相关产品推荐
相关产品推荐

