我发现在 servlet 中创建的新线程不包含 servlet/CDI 上下文。我创建了一个 HelloWorld servlet(如下所示)来试验这个问题。在下面的示例中,您将看到我在一个新线程 (FutureTask) 中运行“doIt()”函数。但它返回 NULL 但是当我直接调用 'doIt()' 方法时,BeanManager 不是 NULL。
/**
* Servlet implementation class HelloWorld
*/
@WebServlet("/HelloWorld")
public class HelloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(HelloWorld.class
.getName());
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<head><title>Hello World Servlet</title></head>");
writer.println("<body>");
writer.println("<h1>Context injection into Thread Experiment</h1>");
try {
// 1. This is NOT working
new Thread(testTask).start();
testTask.get(5000, TimeUnit.SECONDS);
// 2. This is working
//doIt();
} catch (Exception e) {
e.printStackTrace();
}
writer.println("<body>");
writer.println("</html>");
writer.close();
}
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
doIt();
} catch (Exception e) {
e.printStackTrace();
}
}
};
FutureTask<Object> testTask = new FutureTask<Object>(runnable, null);
protected void doIt() throws Exception {
if(getBeanManager() == null) {
throw new Exception( "BEAN MANAGER IS NULL");
}
}
public static BeanManager getBeanManager() {
try {
InitialContext initialContext = new InitialContext();
return (BeanManager) initialContext.lookup("java:comp/BeanManager");
} catch (NamingException e) {
logger.info("Couldn't get BeanManager through JNDI");
return null;
}
}
}
我在网上搜索但找不到一个很好的参考,而不是说这是可能的。如果有人可以帮助我或为我提供一些好的指针来将上下文注入/传递到新线程中,那就太好了。