Java @新注释不起作用
我试着看看CDI的@New注释是否有效——但似乎不行 在我的应用程序中,我创建了这样的类: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
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,以便每次生成一个新对象。