我的团队拥有一个图书馆,该图书馆提供的组件必须可由使用该库的代码引用。我们的一些消费者使用Spring来实例化他们的应用程序。其他人则使用Guice。我们希望获得有关如何提供这些组件的最佳做法的一些反馈。出现的两个选项是:
Configuration
Spring @Import
和可以进行Module
的Guice 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框架无关(例如,如果新的消费者想要使用Dagger实例化其应用,我们根本不需要更改库)
我认为第一种选择更好。如果您的库在bean之间具有相互依赖关系,则第二种方法中出现spring时的@Configuration
代码将为:
一个小建议:
您可以使用Spring工厂,然后在进行Spring Boot时甚至不需要创建@Import
。只需添加一个maven依赖项,它将自动加载配置。
现在,在这种情况下,请确保您正确使用依赖项。由于您的代码将同时包含spring和Juice依赖代码,因此您将为该库的maven / gradle模块添加依赖关系。这意味着,使用guice的消费者会因为您的图书馆而获得所有春季商品。有多种方法可以解决此问题,具体取决于您选择的构建系统,只是想将其启动]]