古斯用户!我在这里遇到了一种情况,我可以找到解决方法,但我对我的解决方案不满意。它与Using the provider from two different scopes非常相似,但那里的答案不适合我的情况。
我有一个这样的课程,我在很多地方都注入了它:
MyBusinessClass {
@Inject
MyBusinessClass(@AuthenticatedUser User user) {};
}
直到过去的某个时刻,我刚刚@AuthenticatedUser User
从网络会话中得到了,所以我有:
bind(User.class).annotatedWith(AuthenticatedUser.class).toProvider(new AuthenticatedUserProvider());
...
public static class AuthenticatedUserProvider implements Provider<User> {
@Inject
Provider<Session> session;
public User get() {
return SessionUtil.getUserFromSession(session.get());
}
}
问题:
在我需要MyBusinessClass
在不同的 Guice 范围内(以及在请求范围之外)使用相同的内容之前,这非常有效。我创建了一个 JobScope,与 Guice 文档中的范围示例非常相似,创建了一种 JobSession,将其绑定到 JobScope,并将使用@AuthenticatedUser User
时要注入的实例MyBusinessClass
放入 JobSession 中。
这就是我不为我所做的事情感到自豪的地方。我“改进”了我的提供程序以尝试@AuthenticatedUser User
为所有范围提供,我最终得到了这个丑陋的提供程序:
public static class AuthenticatedUserProvider implements Provider<User> {
@com.google.inject.Inject(optional=true)
Provider<Session> session;
@com.google.inject.Inject(optional=true)
Provider<JobSession> jobSession;
@Override
public User get() {
try {
return SessionUtil.getUserFromSession(session.get());
} catch (Exception e) {
try {
return SessionUtil.getUserFromJobSession(jobSession.get());
} catch (Exception ee) {
throw new IllegalStateException("Current scope doesn't have a auth user!");
}
}
}
}
提供者采用试错法来查找可用的会话(Web 会话或作业会话),并返回用户获得的第一个会话。它之所以起作用,是@com.google.inject.Inject(optional=true)
因为范围是相互排斥的。
有没有更好的方法来实现这一目标?我只想为透明使用它的任何范围MyBusinessClass
注入@AuthenticatedUser User
,并让 Guice 模块/提供者找到正确的位置来获得令人满意的实例。