使用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不能用它。
答案 0 :(得分:0)
'ThreadLocal模式'最初用于生成HTTP请求数据,Vaadin应用程序实例可以轻松地用于Vaadin应用程序的其余部分 - 而不需要传递变量引用。
那就是说,如果使用CDI,我认为没有任何ThreadLocal变量你应该没问题。只需在任何需要的地方使用RequestScoped和VaadinScoped变量。