当前位置: 首页 > 知识库问答 >
问题:

如何通过weld在Java SE中获得ApplicationScoped producer?

蒋畅
2023-03-14

我正在尝试使用weld在我的JavaSE程序中实现依赖注入,但在使用应用程序范围的生产者时遇到了问题。这是我用最少的代码解决的问题。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 private MyResource。bean在org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:392org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:530)位于org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(Concurrent Validator.gava:68)位于org.jboss.weld.bootstap.ConcurrentValidator$1.doWorks(ConverrentValidator.cava:66)位于org.gboss.welder.executor.IteriveWorkerTaskFactory$1.call(IterTaskFactory.java:60),位于org.j老板.weld.ecutor.IterveWorkerTaskFactory$1.call位于java.lang.Thread.run(Thread.java:745)的java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPool Executor.java:1142。UnproxyableResolutionException:WELD-001435:普通范围的bean类MyBean不可代理,因为它没有参数构造函数-Producer Method[MyBean],其限定符[@Any@Default]声明为[[BackedAnnotatedMethod]@Produces@ApplicationScoped public BeanProducter.beanProducter()]。在org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:214),在org.jboss.weld.uil.Proxies.getUnproxyableTypeException

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

但将注入点的范围设置为@ApplicationScoped与默认范围相同,即为每个请求创建一个新实例。

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

共有1个答案

杭涵映
2023-03-14

发生这种情况是因为@Application ationScoped是一个普通范围,它需要是可代理的。要可代理,您需要一个无参数构造函数。

澄清你的一个观点

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

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

 类似资料:
  • 我需要在其中运行 但是,有一个错误是我无法从maven存储库中获取pom文件。

  • 我正在通过添加CDI重构旧模块。 我以 和 为了进行测试,我创建了一个文件: 为了测试它,我正在做这个博客中显示的 和 现在,当我试图测试逻辑时,我做到了 当我运行它时,两个测试属性都是inject,但是我得到了NPE,因为实例中的属性没有被赋值。 为什么Weld不能识别中的属性? JDK 7,焊接2.2.10,Junit 4.12 更新:发布问题后,开始尝试一个更简单、全新的项目(只有两个接口和

  • 文档页面显示boto3支持服务配额,但看起来不支持,或者我在这里做了什么不正确的事情? https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/service-quotas.html

  • 问题内容: 我创建了一个包含很多字段的表单,用户可以在其中创建无限的字段。如果用户将更多时间花在CSRF令牌上,则它将过期,并且当他单击提交LARAVEL时,将返回错误CSRF令牌不匹配。那么,如何使用ajax调用获取新的CSRF令牌,以便可以在固定的时间间隔内更新CSRF?我无法刷新或重新加载表格。 问题答案: 只需将其添加到您的脚本中 并确保已将令牌添加到元标记中,如下所示。 希望这对您有用。

  • 我已经将vs代码配置为在windows 7中使用git bash作为终端。 “terminal.integrated.shell.windows”:“C:\Program Files\git\bin\bash.exe” 我已经启用了基于SSH密钥的身份验证来远程访问主机。所有这些都可以在VS代码中的终端内部正常工作。 但是,当使用vscode-remote SSH扩展连接到主机时,我会出现一个错误