我有点困惑,其在下列情况下使用:了解CDI实例<>和获得()VS @Inject
假设servlet创建处理用户的HTTP会话的应用,以及应用程序是这样的:
public class Application extends AbstractHTTPApplication {
@Inject
private Instance<MainView> mainView;
public void setupApplication() {
this.setView(mainView.get());
}
后来我有一个@SessionScoped
豆SSB
,我想注入到每个用户的Bean:
@SessionScoped
public class SSB {}
现在当我在MainView
尝试了常规@Inject SSB ssb;
作为一个领域,我不为每个用户得到一个新的SSB
:
public class MainView {
@Inject
private SSB usersSSB;
public someMethod() {
usersSSB.doSomething();
System.identityHashCode(usersSSB);
}
}
测试有两个用户,我得到了这两个用户的会话usersSSB
的相同实例。我不认为这是可能的...我想,既然是SSB SessionScoped,一个新的将给予每个用户会话,不管它是@Inject
编将参考该用户SSB
。
相反,我想:
public class MainView {
@Inject
private Instance<SSB> usersSSB;
public someMethod() {
usersSSB.get().doSomething();
System.identityHashCode(usersSSB.get());
}
}
现在它报告为每个用户不同的usersSSB
,终于。
这里发生了什么?当我后来打电话usersSSB.get()
在每个用户的会话,将在usersSSB.get()
回报同样豆每次同样用户?
我Glassfish上运行3.1.2。
一些更多的信息
的应用类被注入到Servlet的一个新的HttpServletRequest:
public abstract class AbstractCdiApplicationServlet extends
AbstractApplicationServlet {
@Inject
protected Instance<ApplicationWrapper> wrapper;
@Override
protected Application getNewApplication(HttpServletRequest request)
throws ServletException {
return wrapper.get().getApplication();
}
...etc etc
而且ApplicationWrapper
是SessionScoped
豆:
@SuppressWarnings("serial")
@SessionScoped
public class ApplicationWrapper implements Serializable {
@Inject
private AbstractCdiApplication application;
public AbstractCdiApplication getApplication() {
return application;
}
}
隐而不宣“T这意味着调用@Inject SSB usersSSB
随时随地的MainView(或任何该用户的会话中对象)应该给我说,用户的会话作用域的bean,并始终同会话范围的bean,为每个用户的会话?含义 - 针对不同用户的不同用户SSB,因为每个用户都有不同的会话。
毕竟,Application
本身是一个SessionScoped
bean,通过servlet的getNewApplication
方法注入并附加到用户的HTTP Session中?我的意思是,应用程序对象注入并连接MainView类毕竟是正确的?这意味着MainView是一个会话范围的bean,不是吗?
我只是想弄清楚这一切是如何工作的,我猜。谢谢您的帮助!
这很奇怪。你有这个样本可用于测试吗? – LightGuard 2012-03-27 16:48:25
老实说,我没有一个足够牢固的句柄来做一个简单的测试用例......是否有一个工作的maven原型可以用一个http servlet为你启动,为每个新会话创建一个应用程序?我可以用它来构建一个测试项目并发布它。 – 2012-03-28 21:38:59