Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @新注释不起作用_Java_Jakarta Ee_Cdi - Fatal编程技术网

Java @新注释不起作用

Java @新注释不起作用,java,jakarta-ee,cdi,Java,Jakarta 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 produ

我试着看看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 annotation注释了注入——但它打印出三个相同的日期,如下所示:

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

为什么?

从producer方法中删除@SessionScoped。返回的日期已绑定到会话,不会再次调用。

我不确定您对@New限定符的期望值。记住,它在CDI 1.1中已被弃用。阅读这本书可能有用

总之,@New与托管Bean和会话Bean相关,而不是与生产者相关。规范规定

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

所以当你写作的时候

@New @Inject
private Date d1;

您的制作人未使用,使用的是Date类。为什么总是使用当前日期。

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

如果没有@New annotation,CDI将创建一个代理实例,而不是实际实例。现在@New instance没有可用的代理,因为只请求了一个新实例。因此,不需要调用生产者方法。。使用@New时,不调用@products注释

示例代码:

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上找到以下示例:

简短回答:删除@New和@SessionScoped

我们试图使CDI规范尽可能容易阅读。因此,请花点时间阅读并检查我的答案。返回的日期不是生产者中编码的随机日期,但问题的确切日期对您来说似乎不是一个奇怪的巧合?一个简短的解释是值得的:使用@New完全跳过生产者,并创建一个简单的数据对象的新实例-因此所有对象将指向当前数据,尽管它们不相等@SessionScoped导致在单个会话中,您将始终获得在生产者中创建的相同随机对象。作用域应该是未指定的或@Dependent,以便每次生成一个新对象。