2012-09-22 33 views
0

在使用ThreadLocal变量时是否可以使用CDI的@Inject注释? 有一个片段:Vaadin:使CDI和ThreadLocal成为朋友

@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

'ThreadLocal模式'最初用于使得HTTP请求数据和Vaadin应用程序实例可以很容易地用于Vaadin应用程序的其余部分,而无需传递变量引用。

这就是说,我认为你应该没有任何ThreadLocal变量罚款,如果使用CDI。只要使用RequestScoped和VaadinScoped变量,只要你需要它们。

+0

谢谢你的回答。我试过这个,但似乎与初始化/注入链的问题... – Dmitry