【发布时间】:2019-12-05 05:18:52
【问题描述】:
我的团队拥有一个库,该库提供的组件必须可由使用该库的代码引用。我们的一些消费者使用 Spring 来实例化他们的应用程序;其他人使用Guice。我们想要一些关于如何提供这些组件的最佳实践的反馈。出现的两个选项是:
- 让我们的库提供一个 Spring
Configuration供消费者使用@Import和一个 GuiceModule供他们使用install。 - 让我们的库提供一个
ComponentProvider单例,它提供了获取库提供的相关组件的方法。
这些会是什么样子的快速草图:
两种方法都存在
// In their code
@AllArgsConstructor(onConstructor = @__(@Inject))
public class ConsumingClass {
private final FooDependency foo;
...
}
第一种方法
// In our code
@Configuration
public class LibraryConfiguration {
@Bean public FooDependency foo() {...}
...
}
---
public class LibraryModule extends AbstractModule {
@Provides FooDependency foo() {...}
...
}
========================
========================
// In their code
@Configuration
@Import(LibraryConfiguration.java)
public class ConsumerConfiguration {
// Whatever initiation logic they want - but, crucially, does
// *not* need to define a FooDependency
...
}
---
// *OR*
public class ConsumerModule extends AbstractModule {
@Override
public void configure() {
// Or, simply specify LibraryModule when creating the injector
install(new LibraryModule());
...
// As above, no requirement to define a FooDependency
}
}
第二种方法
// In our code
public class LibraryProvider {
public static final INSTANCE = buildInstance();
private static LibraryProvider buildInstance() {...}
private static LibraryProvider getInstance() {return INSTANCE;}
}
========================
========================
// In their code
@Configuration
public class ConsumerConfiguration {
@Bean public FooDependency foo() {
return LibraryProvider.getInstance().getFoo();
}
...
}
// or equivalent for Guice
对于这种情况是否有公认的最佳实践?如果不是,那么每种方法的优缺点是什么,或者我还没有想到的另一种选择?第一种方法的优点是消费者不需要编写任何代码来初始化依赖项,并且 DI 框架可以覆盖依赖项(例如,使用模拟依赖项进行测试);而第二种方法的优点是与 DI 框架无关(例如,如果一个新消费者想使用 Dagger 来实例化他们的应用程序,我们根本不需要更改库)
【问题讨论】:
标签: java spring dependency-injection guice