Ban*_*ore 3 java spring dependency-injection guice
我想在 Guice 中将接口与 Impl 绑定时传递构造函数参数。
有几个解决方案,但我没有对这些接口/Impl 的代码访问权限。它们是由其他团队开发的,我已将它们包含在我的项目中。
目前我们正在使用 Spring DI,并且正在迁移到 Guice。所以我需要定义类似的东西
<bean name="clientWrapper" class="com.wrapper.client.ClientWrapper">
<constructor-arg index="0" value="${server.ip}" />
<constructor-arg index="1" value="${server.port}" />
</bean>
Run Code Online (Sandbox Code Playgroud)
在吉斯。但传递那些构造函数参数。
bind(IClientWrapper.class).to(ClientWrapper.class);
Run Code Online (Sandbox Code Playgroud)
如何在不使用 Provider 的情况下实现这一目标?
Provides
我认为你最好的选择是方法和toConstructor
绑定的组合。
@Provides
当您的对象具有无法单独通过类型解决的依赖项时,请使用方法绑定。
public class ProvidesModule extends AbstractModule {
@Provides
IClientWrapper clientWrapper(@Named("server.ip") String ip,
@Named("server.port") int port) {
return new ClientWrapper(ip, port);
}
}
Run Code Online (Sandbox Code Playgroud)
就整体代码大小而言,这并不比 Spring 大很多,而且是类型安全的。
当构造函数仅具有可以单独通过类型计算的依赖项时,请使用 toConstructor 绑定
protected void configure() {
try {
bind(TransactionLog.class).toConstructor(
DatabaseTransactionLog.class.getConstructor(DatabaseConnection.class));
} catch (NoSuchMethodException e) {
addError(e);
}
}
Run Code Online (Sandbox Code Playgroud)
最后一个选择:
我们的遗产:
interface LegacyThing {
}
class LegacyThingImp implements LegacyThing {
public LegacyThingImp(String test) {
System.out.println(test);
}
}
Run Code Online (Sandbox Code Playgroud)
是我在GitHub上的魔法提供者。这需要一个实现类和依赖项列表(如Key
s),然后通过 Magic(或反射)找到正确的构造函数。
public class TestMagic {
public static void main(final String... arg) {
Guice.createInjector(
new AbstractModule() {
@Override
protected void configure() {
bind(String.class).annotatedWith(Names.named("testString")).toInstance("Guice!");
bind(LegacyThing.class).toProvider(new MagicLegacyProvider<>(LegacyThingImp.class, Key.get(String.class, Names.named("testString"))));
}
}).getInstance(LegacyThing.class);
}
}
Run Code Online (Sandbox Code Playgroud)