2012-09-22 75 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