为什么不能注入java.util.Random?
Why can't java.util.Random be injected ?
将 java.util.Random 注入 Bean 时,部署失败:
CDI deployment failure:WELD-001408: Unsatisfied dependencies for type Random with qualifiers @Default at injection point [BackedAnnotatedField] @Inject myPackage.MyBean.random
问题:为什么不能注入 java.util.Random class 的实例?
我创建了一个 class A,它具有相似的属性(例如具有默认可见性的 final 方法),可以毫无问题地注入。这是代码:
@Named
@SessionScoped
public class MyBean implements Serializable {
@Inject private java.util.Random random; // (R)
@Inject private A a;
...
}
public class A implements Serializable {
int n;
public A() { System.out.println("A"); }
public A(int n) { this.n = n; }
final int nextInt(int bound) { return bound -n; }
}
如果 (R) 行被注释掉,一切都会部署并运行良好。
您的 class 必须作为 bean 被 CDI 发现。为此你必须做这样的事情:
在其上放置一个bean 定义注解。由于 @Model 是一种刻板印象,这就是它起作用的原因。像 @Named 这样的限定符不是定义注解的 bean,这可能是它不起作用的原因。
您不能将 java.util.Random
作为 bean 注入,因为您的应用程序无法识别该给定类型的任何 bean 或生产者。
您有 beans.xml
和发现 all
- 这意味着 CDI 将在您的应用程序 中 类 并尽可能将它们变成 beans (如果它们满足 CDI 规范规定的要求)。 java.util.Random
与您的应用程序 不是 ,因此 CDI 不知道如何为您实例化此类 bean 并抛出异常。另一方面,您的 A
bean 在您的应用程序中,并且由于您发现 all
并且它满足要求,CDI 将认为它是一个 bean(@Dependent
范围 @Any
和 @Default
限定词)。
为了能够注入 java.util.Random
,您需要告诉 CDI 如何做到这一点。您可以使用生产者方法相当轻松地实现这一目标。请注意,生产者方法必须在 CDI bean 中声明,以便 CDI 找到它。
@Produces
@Dependent //choose desired scope, or none and it will be dependeny
// you can also add qualifiers, optional
public Random produceRandom() {
return new Random();
}
有了上面的生产者,CDI 将不会检测到它并且能够在您需要时创建这样的对象@Inject
。
要将 class 作为 bean 被发现,它必须部署在 bean 存档中,请参阅 http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_archive
据我了解,这也包括 target/classes 之类的内容,但 不是 rt.jar 的内容。
因为我认为您的问题只是关于一般机制而不是关于 "how-to-inject-Random",所以我就此打住。请参阅有关如何通过生产者方法使随机可注入的其他答案。
将 java.util.Random 注入 Bean 时,部署失败:
CDI deployment failure:WELD-001408: Unsatisfied dependencies for type Random with qualifiers @Default at injection point [BackedAnnotatedField] @Inject myPackage.MyBean.random
问题:为什么不能注入 java.util.Random class 的实例?
我创建了一个 class A,它具有相似的属性(例如具有默认可见性的 final 方法),可以毫无问题地注入。这是代码:
@Named
@SessionScoped
public class MyBean implements Serializable {
@Inject private java.util.Random random; // (R)
@Inject private A a;
...
}
public class A implements Serializable {
int n;
public A() { System.out.println("A"); }
public A(int n) { this.n = n; }
final int nextInt(int bound) { return bound -n; }
}
如果 (R) 行被注释掉,一切都会部署并运行良好。
您的 class 必须作为 bean 被 CDI 发现。为此你必须做这样的事情:
在其上放置一个bean 定义注解。由于 @Model 是一种刻板印象,这就是它起作用的原因。像 @Named 这样的限定符不是定义注解的 bean,这可能是它不起作用的原因。
您不能将 java.util.Random
作为 bean 注入,因为您的应用程序无法识别该给定类型的任何 bean 或生产者。
您有 beans.xml
和发现 all
- 这意味着 CDI 将在您的应用程序 中 类 并尽可能将它们变成 beans (如果它们满足 CDI 规范规定的要求)。 java.util.Random
与您的应用程序 不是 ,因此 CDI 不知道如何为您实例化此类 bean 并抛出异常。另一方面,您的 A
bean 在您的应用程序中,并且由于您发现 all
并且它满足要求,CDI 将认为它是一个 bean(@Dependent
范围 @Any
和 @Default
限定词)。
为了能够注入 java.util.Random
,您需要告诉 CDI 如何做到这一点。您可以使用生产者方法相当轻松地实现这一目标。请注意,生产者方法必须在 CDI bean 中声明,以便 CDI 找到它。
@Produces
@Dependent //choose desired scope, or none and it will be dependeny
// you can also add qualifiers, optional
public Random produceRandom() {
return new Random();
}
有了上面的生产者,CDI 将不会检测到它并且能够在您需要时创建这样的对象@Inject
。
要将 class 作为 bean 被发现,它必须部署在 bean 存档中,请参阅 http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_archive
据我了解,这也包括 target/classes 之类的内容,但 不是 rt.jar 的内容。
因为我认为您的问题只是关于一般机制而不是关于 "how-to-inject-Random",所以我就此打住。请参阅有关如何通过生产者方法使随机可注入的其他答案。