Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.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
如何通过weld在Java SE中获得应用程序范围的生产者?_Java_Scope_Cdi_Weld - Fatal编程技术网

如何通过weld在Java SE中获得应用程序范围的生产者?

如何通过weld在Java SE中获得应用程序范围的生产者?,java,scope,cdi,weld,Java,Scope,Cdi,Weld,我试图使用weld在我的JavaSE程序中实现依赖项注入,但在使用应用程序范围的生产者时遇到了问题。这是我的问题的PoC,代码最少。MyBean类: public class MyBean implements Serializable{ private int value; public MyBean(int value) { this.value = value; } public int getValue() { return value; }

我试图使用weld在我的JavaSE程序中实现依赖项注入,但在使用应用程序范围的生产者时遇到了问题。这是我的问题的PoC,代码最少。
MyBean
类:

public class MyBean implements Serializable{
  private int value;

  public MyBean(int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }

  public void setValue(int value) {
    this.value = value;
  }
}
注射点:

@Path("api")
public class MyResource implements Serializable {
  @Inject
  private MyBean bean;

  @GET
  @Path("bean")
  @Produces(MediaType.APPLICATION_JSON)
  public Response getBean() {
    return Response.ok(bean).build();
  }
}
我希望其生成实例为
@ApplicationScoped
的生产者是:

public class BeanProducer {

  @Produces
  @ApplicationScoped
  public MyBean beanProducer(){
    System.out.println("producing");
    return new MyBean(42);
  }
}
所有这些都集中在一个主类中:

public class Main {
  public void main(@Observes ContainerInitialized event) {
    try {
      URI baseUri = UriBuilder.fromUri("http://localhost").port(1234).build();
      ResourceConfig config = new ResourceConfig(MyResource.class)
          .register(JacksonFeature.class);
      SimpleServer server = SimpleContainerFactory.create(baseUri, config);
      System.in.read();
      server.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
当我尝试运行此程序时,会出现以下异常:

线程“main”中出现异常 org.jboss.weld.exceptions.DeploymentException:weld-001410: 注入点[BackedAnnotatedField]@Inject@ApplicationScoped 私有MyResource.bean在上具有不可代理的依赖项 org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:392) 在 org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:293) 在 org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134) 在 org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:167) 在 org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:530) 在 org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68) 在 org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66) 在 org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60) 在 org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53) 在java.util.concurrent.FutureTask.run(FutureTask.java:266)处 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在java.lang.Thread.run(Thread.java:745)处,由以下原因引起: org.jboss.weld.exceptions.Unproxy解析异常:weld-001435: 普通作用域bean类MyBean不可代理,因为它没有 没有带限定符[@Any]的args构造函数-Producer方法[MyBean] @默认值]声明为[[BackedAnnotatedMethod]@products @应用程序复制的公共BeanProducer.BeanProducer()]。在 org.jboss.weld.util.Proxies.GetUnproxiableClassException(Proxies.java:214) 在 org.jboss.weld.util.Proxies.GetUnproxiableTypeException(Proxies.java:178) 在 org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:390) ... 还有12个

如果我为producer定义一个范围,它将不起作用。 如果我将注入点范围设置为
@ApplicationScoped
,并且producer没有任何范围,那么它可以按照我的需要工作,这意味着我将在我的应用程序的整个生命周期中拥有一个bean实例

但是将注入点的作用域设置为
@ApplicationScoped
与默认作用域相同,即每个请求都有一个新实例


这一切背后的原因是什么?

之所以发生这种情况,是因为
@ApplicationScoped
是一个正常的作用域,它需要可代理。要可代理,您需要一个无参数构造函数

澄清你的一点

it works as I want, means I will have a single instance of the bean in the entire lifecycle of my app.

这是不准确的。注入点不定义范围,生产者定义。Java中没有类型安全的方法可以做到这一点,因为您可以有一个producer字段。

添加默认构造函数会使依赖项变得不明确,因为weld不知道是使用producer还是直接注入bean本身。