【发布时间】:2017-03-19 04:18:13
【问题描述】:
在涉及 Guice 和避免非 Guice 单例时,我有一个小问题。考虑一个多模块项目,其中有 3 个模块:shared、frontend 和 backend。 frontend 和 backend 都在 shared 模块内使用 Profiling 类的实例(对方法进行计时,并在整个项目中广泛使用)。
几乎每个类都需要使用这个Profiling 实例(包括在用户连接时动态创建的User 对象)。
如果每个单独的类都需要Profiling 类的实例,那么不同的实现方法存在缺陷:
方案一(在构造函数中,复制到实例字段中):
private final Profiling profiling;
@Inject
public User(Profiling profiling, String username)
缺点:您必须在每个构造函数中包含一个Profiling 对象。这很麻烦,而且有点毫无意义。您还必须静态存储 Guice 的 Injector(或注入它),以便您可以即时创建 User 对象,而不仅仅是在首次加载程序时。
解决方案 2(仅作为实例字段):
@Inject
private Profiling profiling;
public User(String username)
缺点:与上面类似,您必须使用 Guice 的 Injector 来实例化每个对象。这意味着要动态创建User 对象,您需要在创建User 对象的类中的Injector 实例。
解决方案 3(作为一个(主)类中的静态字段,由我们手动创建)
public static final Profiling PROFILING; // Can also use a get method
public Application() {
Application.PROFILING = injector.getInstance(Profiling.class)
}
缺点:违背 Guice 的/依赖注入建议 - 创建一个静态访问(通过 Application.PROFILING.start())的单例 Profiling 对象违背了 Guice 的目的?
解决方案 4(作为每个类中的静态字段,由 Guice 注入)
@Inject
private static Profiling profiling;
// You need to request every single class:
// requestStaticInjection(XXXX.class)
缺点:同样,这违背了 Guice 的/依赖注入建议,因为它是静态注入。我还必须请求 Guice 需要将 Profiler 注入的每个类(这也很麻烦)。
有没有更好的方法来设计我的项目并避免回到我过去使用的单例设计模式?
TL;DR:我希望能够跨每个类访问此 Profiling 实例(每个模块一个),而不会退回到单例设计模式。
谢谢!
【问题讨论】:
-
我会按照您的建议(非静态)将它注入到任何 guice 管理的类中。我只会使用构造函数注入(因为它强制手动构造必须传递相同的参数并且不能创建无效实例)。但是,User 听起来不像是 guice 管理的类。我会(也许,这里没有足够的信息)通过一个可以注入 Profiling 类的 User-factory 来实现它,并抽象出每个用户都有一个分析实例的问题。
标签: java dependency-injection structure guice