基本容器类是您的标准“托管”对象,例如您列出的对象(WebListeners、Filters、Servlet)。这些充当上下文链的根。由于这些是由 CDI 管理的,因此它们注入的任何东西也都受到管理,并且沿着这条线。
如果您的 Servlet(例如)注入 PojoX,PojoX 可以注入 PojoY,等等。游戏是避免new,而是使用 CDI 构造来创建您的 POJO。
至于跨越传统 POJO/CDI 鸿沟,您可以做几件事。
您可以将EventHandler 的实例注入 Servlet,然后将该实例作为参数传递给 POJO。
您可以将该实例作为属性粘贴到请求中,或者在首次创建 Servlet 时将该实例推入 ServletContext。
您可以将 EventHandler 设为 @Singleton,并在其 @PostConstruct 中设置一个静态变量,该变量可通过标准的静态 getInstance 调用返回。
您可以让您的 POJO 直接调用容器进行查找(或调用实用程序函数)。
当然,如果 POJO 可以自己注入,那么就这样做吧。
评论补充:
如果适合您的工作,您可以简单地注入 POJO。
这是一个例子:
@WebServlet(name = "NewServlet", urlPatterns = {"/NewServlet"})
public class NewServlet extends HttpServlet {
@Inject
Instance<Pojo> pojoInstance;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Pojo pojo = pojoInstance.get();
String world = pojo.getWorld();
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet NewServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet NewServlet at " + request.getContextPath() + "</h1>");
out.println("<p>Hello " + world);
out.println("</body>");
out.println("</html>");
}
}
}
public class Pojo {
@Inject
Event<PojoEvent> pojoEventHdlr;
@PostConstruct
public void postConstruct() {
System.out.println("Look, another Pojo!");
}
public String getWorld() {
PojoEvent pe = new PojoEvent("World event pojo fired");
pojoEventHdlr.fire(pe);
return "world";
}
}
public class PojoEvent {
String msg;
public PojoEvent() {
}
public PojoEvent(String msg) {
this.msg = msg;
}
public String toString() {
return "PojoEvent with msg: " + msg;
}
}
@Singleton
public class SingletonPojo {
public void pojoEventObserver(@Observes PojoEvent pe) {
System.out.println("We got a PojoEvent " + pe);
}
}
需要注意的重要一点是,我将Instance<Pojo> 注入到servlet 中,然后在其上使用Instance.get,而不仅仅是直接使用Pojo。这样做的原因是 Servlet 在 Web 应用程序中名义上是单例,所以如果你注入了一个实际的 Pojo,你的所有请求都将使用完全相同的 Pojo 实例(不太可能是你想要的)。
您可以看到 Pojo 触发了事件,我有一个 @Singleton 类观察事件并转储消息。
如果您愿意对遗留代码进行更改,您可以做自己喜欢的事情,并且没有真正需要跳过箍来弥合 CDI 遗留的鸿沟。只需根据需要将它们转入 CDI。