我希望有一个可以触发事件的类。理想情况下,我希望将它放在POJO中(处理POJO中的遗留代码),但我知道这是不可能的。所以相反,我希望POJO可以调用哪些内容来激活事件。
注意:我在使用CDI的Tomcat上,JPA也安装了(在此项目中不能切换到完整的EE服务器)
我不确定它应该是单身/应用程序范围的单身人士,还是应该按照请求(甚至是会话)。所以我的问题是:
什么可以注入事件? (例如@WebListener
,@Singleton
,RequestScoped
,@Stateless
)
哪一个对这个用例最有意义?
POJO如何访问该类/实例(从servlet调用POJO)?
示例代码:
//Is this correct?
@WebListener
public class EventHandler
{
@Inject
@MyEventQualifier
private Event<MyEvent> myEvent;
public void fireEvent(MyEvent anEvent)
{
myEvent.fireAsync( anEvent );
}
}
答案 0 :(得分:1)
基本容器类是您标准的“托管”对象,就像您列出的那样(WebListeners,Filters,Servlets)。这些作为上下文链的根源。由于这些都是由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应用程序中名义上是Singletons,所以如果你注入一个真正的Pojo,你的所有请求都将使用完全相同的Pojo实例(不太可能你想要的)。
你可以看到Pojo触发事件,我有一个@Singleton
类来观察事件并转出消息。
如果您愿意对遗留代码进行更改,您可以按自己喜欢的方式进行更改,并且没有必要跳过桥接来连接CDI&lt; - &gt;遗产鸿沟。只需将它们滚入CDI即可。