【问题标题】:How to create on demand instances?如何创建按需实例?
【发布时间】:2012-11-02 17:39:13
【问题描述】:

在调用Java方法时,必须将新实例作为参数传递,这个新实例怎么可能是由CDI容器创建的?

在以下示例中:我正在向异步 servlet 上下文添加侦听器:

@WebServlet(value = "/example", asyncSupported = true)
public class ExampleServlet extends HttpServlet {

    @Override
    protected void doPost(final HttpServletRequest req,
        final HttpServletResponse resp) throws ServletException,
        IOException {

        // ... some code

        AsyncContext aCtx = req.startAsync(req, resp);
        aCtx.addListener(**new AsyncListener()** {
             // implementation of the async listener
        });
        // ...
    }
}

因此,我希望它由 CDI 容器创建,而不是手动执行这个新的 AsyncListener() 实例化。

当然,我希望每个 aync 上下文都有自己的侦听器实例,否则我只会注入一个带有 @Inject 作为 servlet 类的字段的 AsyncListener。

目前,找不到任何方法来做到这一点。 有人有什么想法可以分享吗?

【问题讨论】:

    标签: java jakarta-ee servlets asynchronous cdi


    【解决方案1】:

    在实例化 bean 时会处理 bean 的注入点,因此很遗憾您无法显式触发注入。这可能(并且希望会)在 CDI 的后续版本中发生变化。

    我知道在某些情况下可以用来解决该限制的一种方法是封装或派生要注入的类,为其提供可注入字段或初始化方法。在这种情况下,它将是 AsyncContext,但您无法控制 HttpServletRequest 将返回的内容,因此此选项在这里不适用。

    也许您可以使用 CDI BeanManager 解决问题 - 但我担心这比调用 new 需要更多的努力

    【讨论】:

      【解决方案2】:

      注入你的听众的Instance。如果侦听器类在依赖范围内,那么对get() 的每次调用都会产生一个新实例。

      @Inject
      private Instance<MyAsyncListener> listenerFactory;
      

      还有:

          aCtx.addListener(listenerFactory.get());
      

      我将变量称为 listenerFactory,因为这就是它在此处使用的方式。

      我在 JBoss AS7.1.1 上对此进行了测试,它使用 Weld 1.1.5 作为其 CDI 提供程序,但我相信这是标准行为。

      【讨论】:

      • 还要注意 CDI 1.0 中记录良好的内存泄漏,其中将实例和相关范围对象注入到更大范围的对象中,但是对于您正在做的事情应该没问题。
      • @LightGuard:好点,但我不得不承认我不确定为什么这个案子是安全的。是因为 servlet 不被视为作用域 bean?
      • 它确实完成了这项工作。谢谢你的回答。
      • 我想得越多,我越想答案是做一些魔法来为异步线程创建一个新的请求范围,然后简单地在其中调用一个监听器的实例范围。不过,我不完全确定该怎么做。
      • @TomAnderson 在这种情况下,servlet 没有作用域,而且从他的代码看起来它是无状态的,所以即使容器创建了很多它们,它们也会很快得到 GC。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-02
      • 2013-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多