@New注释不起作用

时间:2015-02-07 07:05:03

标签: java java-ee cdi

我尝试CDI的@New注释是否有效 - 而且似乎没有。

在我的应用程序中,我创建了这样的类:

package pl.piotrek;
import java.util.Date;
import javax.enterprise.inject.Produces;
import javax.enterprise.context.SessionScoped;
public class DateFactory {
    public @Produces @SessionScoped Date produceDate() {
        return new Date((long)(Math.random() * 2000000000000L));
    }
}

然后我尝试在我的servlet中使用它:

package pl.piotrek;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
import java.util.Date;
import javax.inject.Inject;
import javax.enterprise.inject.New;
@WebServlet("/HelloWorld")
public class MyServlet extends HttpServlet {
    @New @Inject
    private Date d1;
    @New @Inject
    private Date d2;
    @New @Inject
    private Date d3;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        PrintWriter writer = resp.getWriter();
        writer.println(d1 + "\n" + d2 + "\n" + d3);
        writer.close();
    }
}

我预计servlet将打印出三个不同的日期 - 我使用@New注释注释了注入 - 但它打印了三个相同的日期,如:

Sat Feb 07 07:53:36 CET 2015
Sat Feb 07 07:53:36 CET 2015
Sat Feb 07 07:53:36 CET 2015

为什么?

4 个答案:

答案 0 :(得分:1)

简短回答:移除@New@SessionScoped

答案 1 :(得分:0)

从producer方法中删除@SessionScoped。返回的Date绑定到会话,不会再被调用。

答案 2 :(得分:0)

我不确定您对@New限定符的期望是什么(请记住它在CDI 1.1中已弃用)。阅读corresponding section the spec可能很有用。

无论如何,@New与Managed Bean和Session Beans(EJB)不是生产者有关。规范说明

  

请注意,此第二个bean存在 - 并且可能已启用且可用   用于注入 - 即使第一个bean被禁用,如下所定义   启用和禁用Bean,或者如果bean类部署在外部   Bean归档中定义的bean归档文件,因此不是   在Packaging和中定义的bean发现过程中发现的   部署。容器通过检查发现@New合格的bean   其他已启用的bean的注入点。

所以当你写

@New @Inject
private Date d1;

您的制作人未使用,它是使用的Date类。您始终拥有当前日期的原因。

答案 3 :(得分:-1)

使用@New注释CDI只创建一个使用@New注释值定义的类的新实例。如果省略该值,则采用声明的注入点的类型。

没有@New注释CDI创建代理实例而不是真实实例。现在使用@New实例,没有可用的代理,因为只请求了一个new()实例。因此不需要调用生成器方法..使用@New不会调用@Produces注释。

示例代码:

package pl.piotrek;

import java.util.Date;
import javax.enterprise.inject.New;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(CdiRunner.class)
public class AtNewAndProducerTest {

    @Produces
    public Date produceDate() {
        return new Date((long)(Math.random() * 2000000000000L));
    }

    @New @Inject
    private Date d1;

    @New @Inject
    private Date d2;

    @New @Inject
    private Date d3;

    @Inject
    private Date d4;

    @Inject
    private Date d5;

    @Test
    public void test() {
        System.out.println(d1);
        System.out.println(d2);
        System.out.println(d3);
        System.out.println(d4);
        System.out.println(d5);

        // will output something like this:
        // Sat Feb 07 13:16:05 CET 2015
        // Sat Feb 07 13:16:05 CET 2015
        // Sat Feb 07 13:16:05 CET 2015
        // Mon Sep 19 12:31:29 CEST 2005
        // Sat Aug 14 21:51:06 CEST 1999
    }

}

你可以在GitHub上找到这个例子: https://github.com/StefanHeimberg/stackoverflow-28379562