Vaadin:让CDI和ThreadLocal成为朋友

时间:2012-09-22 14:54:15

标签: java-ee vaadin cdi

使用ThreadLocal变量时是否可以使用CDI的@Inject注释? 有一个片段:

@VaadinScoped(VaadinScope.APPLICATION)
 public class AdminApplication extends AbstractCdiApplication implements HttpServletRequestListener {

 private static ThreadLocal<AdminApplication> threadLocal = new ThreadLocal<AdminApplication>();

 @Inject
 private Instance<Lang> lang;

 @Override
 public void init() {
    setInstance(this);
    setLocale(Lang.RU_RU);
    setMainWindow(new LoginWindow());
 }

 @Override
 public final void setLocale(Locale locale) {
    getInstance().lang.get().setLocale(locale);
    super.setLocale(locale);
 }

    public static AdminApplication getInstance() {
    return threadLocal.get();
 }

 public static void setInstance(AdminApplication application) {
       threadLocal.set(application);
 }

 @Override
 public void onRequestStart(HttpServletRequest request, HttpServletResponse response)  {
    AdminApplication.setInstance(this);
 }

当我尝试调用这些方法时:

public void authenticate(String login, String password) throws Exception {
    if ("user".equals(login) && "querty".equals(password)) {
        loadProtectedResources();
        return;
    }

    throw new Exception("Login failed!");
}

private void loadProtectedResources() {
    String mainWindowCaption = getInstance().lang.get().getText("mainwindow-name");
    setMainWindow(new Window(mainWindowCaption));
}

我通常会得到一个NullPointerException,因为getInstance().lang.get()为空。

郎是:

@VaadinScoped(VaadinScope.APPLICATION)
public class Lang implements Serializable, TextBundle {...}

有趣的是,如果我使用@EJB注释,注入的ejb就在那里(不为空)。另一件事是getInstance().lang是默认实例(在调试中看到这一点),但是当我调用getInstance().lang.get()时它是空的。

我尝试使用直接引用@Inject private Lang lang;,但似乎CDI加上HttpServletRequestListener不能用它。

1 个答案:

答案 0 :(得分:0)

'ThreadLocal模式'最初用于生成HTTP请求数据,Vaadin应用程序实例可以轻松地用于Vaadin应用程序的其余部分 - 而不需要传递变量引用。

那就是说,如果使用CDI,我认为没有任何ThreadLocal变量你应该没问题。只需在任何需要的地方使用RequestScoped和VaadinScoped变量。