[英]Global injectors with Guice
我正在创建一个库并帮助进行人机工程学设计,我将在应用程序启动时创建的注入器传递给库中的不同组件,以便用户可以在某些上下文中执行getInstance()
,而不必预先计划将其粘贴在哪里@Inject
注解。
这是API设计的示例:
public static void main(String[] args) {
// Main injector is created here behind the scenes.
ApexApplication app = new ApexApplication()
app.get("/users/:id", context -> {
// Users can do this instead of @Inject UserDAO dao
UserDAO dao = context.getInstance(UserDao.class)
User user = dao.findUserById(context.param("id"))
//...
})
app.start();
}
为了清楚起见,以下是关键实现细节的链接:
我知道,Guice注入器的最佳实践是在整个应用程序中创建一个并且只有一个,使用它注入所有依赖项,然后将其丢弃。 但是,考虑到我要实现的目标,是否建议使用此方法,或者我应该考虑其他模式吗?
我认为将带注入器的上下文发送给其他所有类以访问注入器不是一个好主意。
还有另一种方法,实际上与@Jameson的MyModuleHelper的想法相似。 DIContainer对注入器进行静态初始化,并提供公共静态API getInjector()。 这样,您就可以拥有仅创建一次的喷射器,并且该喷射器可以用于任何没有样板代码的类:
public final class DIContainer {
private static final Injector injector;
static {
injector = Guice.createInjector(new AppModule());
}
public static Injector getInjector() {
return injector;
}
private DIContainer() {
}
}
用法示例:
ServiceProvider service = DIContainer.getInjector().getInstance(ServiceProvider.class);
可能这篇文章也很有用。
我采纳了您的建议@asch,但对其进行了一些更改,以允许用户设置自己的配置模块。
public class DependencyManager {
private static Injector injector;
private static Logger logger = LoggerFactory.getLogger(DependencyManager.class);
public static Injector initializeWith(ApexConfiguration configuration) {
if(injector == null) {
logger.debug("Initializing injector")
injector = Guice.createInjector(configuration);
}
return getInjector();
}
public static Injector getInjector() {
if(injector == null) {
logger.error("Application hasn't been configured yet.");
return null;
}
return injector;
}
private DependencyManager() {}
}
我不能完全确定它的线程安全性,但是在执行所有测试的过程中,日志记录消息“ Initializing injector
仅显示一次,并且在调用getInjector()
时从未收到NullPointerException
getInjector()
。
我相信这是因为库的结构是在任何其他应用程序操作发生之前DependencyManager
必须且自动初始化的。
欢迎提出任何意见/建议以改善此情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.