我尝试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
为什么?
答案 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