0

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

@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 一起添加不适用于它。

4

1 回答 1

0

'ThreadLocal 模式' 最初用于使 HTTP 请求数据和 Vaadin 应用程序实例易于用于 Vaadin 应用程序的其余部分 - 无需传递变量引用。

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

于 2012-09-25T07:50:16.130 回答