了解cdi实例<>和.get()vs @Inject

时间:2012-03-26 21:36:37

标签: java-ee java-ee-6 cdi jboss-weld

我对以下情况中使用哪个有点困惑:

假设servlet创建一个处理用户http会话的Application,应用程序是这样的:

public class Application extends AbstractHTTPApplication {

@Inject
private Instance<MainView> mainView;

public void setupApplication() {
   this.setView( mainView.get() );
}

后来我有一个@SessionScoped bean SSB我要注入每个用户的bean:

@SessionScoped
public class SSB {}

现在,当我在@Inject SSB ssb;中尝试使用常规MainView作为字段时,我没有为每个用户获得新的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()每次都会为相同的用户返回相同的bean 吗?

我在Glassfish 3.1.2上运行。

更多信息

Application类正在新的HttpServletRequest上注入到Servlet中:

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

ApplicationWrapperSessionScoped bean:

@SuppressWarnings("serial")
@SessionScoped
public class ApplicationWrapper implements Serializable {
@Inject
private AbstractCdiApplication application;

public AbstractCdiApplication getApplication() {
    return application;
}
 }

这是不是意味着在MainView中调用@Inject SSB usersSSB(或该用户会话中的任何对象)应该给我该用户的会话范围的bean,并始终对于每个用户的会话,相同的会话范围的bean?含义 - 针对不同用户的不同用户SSB,因为每个用户都有不同的会话。

毕竟,Application本身是一个SessionScoped bean,通过servlet的getNewApplication方法注入并附加到用户的HTTP会话中?我的意思是,毕竟正是Application对象注入并附加了MainView类,对吧?这意味着MainView是一个会话范围的bean,不是吗?

我猜,我只想弄清楚这一切是如何运作的。谢谢你的帮助!

1 个答案:

答案 0 :(得分:7)

这是因为'@Inject Instance&lt;&gt;'是动态获得的,不像'@Inject'

如果你在ApplicationScoped bean中执行'@Inject',那么只能获得一次注入,因此ApplicationScoped bean将为所有用户提供相同的引用

如果你在'@Inject Instance&lt;&gt;'上调用.get()每次调用.get()

时,都会动态获取SSB的引用

有关注射的更多信息,请参阅此处:http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/injection.html