【问题标题】:How inject a Singleton class annotated with @Startup? @Inject, @Resource, @EJB ou BeanManager?如何注入带有@Startup 注释的单例类? @Inject、@Resource、@EJB 还是 BeanManager?
【发布时间】:2018-08-24 14:50:37
【问题描述】:

我有这样的课程:

@Singleton
@Startup
@Default
public class A {

    private Manager manager; // Manager is an interface

    @PostConstruct
    public void init() {
      if (some rule is true) {
         manager = new ManagerA();
      } else {
         manager = new ManagerB();
      }
    }

    public Manager getManager() {
       return manager;
    }

}

现在我有一个像这样的端点 JAX-RS:

@Path("mypath")
public class B {

    // @Inject vs @Resource vs @EJB - my doubt
    private A objA;

    @POST
    @Path("resource")
    @Consumes("application/json")
    @Produces("application/json")
    public Response myMethod(String param) {

        objA.getMamager().executeSomeMethod(param);

        return Response.status(HttpStatus.SC_OK).build();
    }
}

当我注入对象时,无论我使用什么注释,它都会出错。一些错误:

  • WFLYWELD0044:将资源注入 CDI 托管 bean 时出错。不能 找到一个名为

  • 的资源
  • 启动服务失败原因: org.jboss.weld.exceptions.DeploymentException:WELD-001408: 带有限定符 @Default 的类型 A 的不满足依赖项

如何解决?

【问题讨论】:

  • 如果您使用@Inject(我建议),那么bean 的发现取决于您何时拥有beans.xml 以及您拥有的bean 发现模式。如果设置错误,您最终会得到您所看到的 - WELD-001408: Unsatisfied dependencies...。简而言之,这意味着没有找到带有限定符 @Default 的此类 bean A。尝试将空的beans.xml 添加到您的应用程序中,并将您的A bean 标记为@ApplicationScoped(保留它@Singleton@Startup)。拥有@Default 限定符是多余的,您可以将其删除(默认情况下假定)。

标签: jakarta-ee dependency-injection jax-rs cdi inject


【解决方案1】:

您的@Singleton @Startup bean 可能存在竞争条件以及它所依赖的某些东西。我自己已经看过好几次了。特别是当@Startup bean 依赖于容器必须初始化的另一个工具(q.v. JPA、JMS、CDI 等)时。如果是这种情况,请删除 @Startup 并让 bean 在第一次注入依赖项时进行初始化。

如果您真的、真的、真的需要 bean 成为 @Startup,请尝试隔离它失败的依赖项,并在 @DependsOn(depends="blah blah blah") 注释中标记该依赖项。

我使用的另一种解决方法,如果您无法删除 @Startup,请隔离依赖项并通过 JNDI(老派)惰性注入它。有时,所有的花里胡哨只会妨碍“它是如何真正完成的”。 /咧嘴笑

告诫购买者

【讨论】:

    猜你喜欢
    • 2015-12-12
    • 2012-01-01
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多