如何在 CDI AfterDeploymentValidation 生命周期事件期间实例化一个 bean 并将参数传递给 bean?
How to instantiate a bean during the CDI AfterDeploymentValidation lifecycle event and pass a parameter to the bean?
我正在开发一个 CDI 扩展,它需要用所有发现的具有特定注释的 bean 填充 HashMap
,然后在 AfterDeploymentValidation
生命周期事件期间实例化一个 @ApplicationScoped
bean 并将 HashMap
传递给新实例化的 bean。
使用下面的代码,我可以找到任何用 @CQRSCommandHandler
注释的 bean,并使用 bean 的名称和注释上设置的参数填充 HashMap
。
public class CQRSExtension implements Extension {
private Map<String, String> discoveredCommandHandlers = new HashMap<String, String>();
public <T> void processAnnotatedType(@Observes @WithAnnotations({ CQRSCommandHandler.class }) ProcessAnnotatedType<T> processAnnotatedType) {
AnnotatedType<T> annotatedType = processAnnotatedType.getAnnotatedType();
String commandName = annotatedType.getAnnotation(CQRSCommandHandler.class).command().getName();
String handlerName = annotatedType.getJavaClass().getName();
discoveredCommandHandlers.put(commandName, handlerName);
}
}
我正在苦苦挣扎的是我应该如何急切地实例化这个 bean 并将 HashMap
传递给这个 bean。
我可以找到很多示例,例如这个 (http://ovaraksin.blogspot.co.uk/2013/02/eager-cdi-beans.html),它们展示了如何急切地实例化任何具有特定注释的 bean,但是我不知道如何实例化一个特定的 bean 并传递一个HashMap
给这个豆子。
理想情况下,我不希望使用反射来扫描注释。
如何实例化一个特定的 bean 并将 HashMap
传递给该 bean?或者,有没有更好的方法可以在不使用反射的情况下获得相同的结果?
为什么需要急切实例化 bean?
您有两个选择:
- 改为将扩展注入到 bean 中,并在其中使用
HashMap
。
例如
@Inject
public MyAppScopedBean(MyExtension extension) {
this.someHashMap = extension.getHashMap();
}
- 将
HashMap
传递给生产者方法以提供对 HashMap
的注入支持。
如果你真的想自己实例化 bean,你实际上是在试图打破 DI 的概念。
如果可以选择运行时扫描,您可能想看看 https://code.google.com/p/reflections/
它提供了一个简单而强大的 API.
否则看看这个link。 16.10 中的示例非常相似,因为在示例中 bean 中的值是由扩展设置的。您可以调整该示例以将 hashMap 设置到您的应用程序范围的 bean 中。您只需使用像这样的观察者方法
ApplicationScopedBean void processInjectionTarget(
@Observes ProcessInjectionTarget<ApplicationScopedBean> pit) { ...
并在包装的 InjectionTaget 实现中将映射设置到 bean 中。
我正在开发一个 CDI 扩展,它需要用所有发现的具有特定注释的 bean 填充 HashMap
,然后在 AfterDeploymentValidation
生命周期事件期间实例化一个 @ApplicationScoped
bean 并将 HashMap
传递给新实例化的 bean。
使用下面的代码,我可以找到任何用 @CQRSCommandHandler
注释的 bean,并使用 bean 的名称和注释上设置的参数填充 HashMap
。
public class CQRSExtension implements Extension {
private Map<String, String> discoveredCommandHandlers = new HashMap<String, String>();
public <T> void processAnnotatedType(@Observes @WithAnnotations({ CQRSCommandHandler.class }) ProcessAnnotatedType<T> processAnnotatedType) {
AnnotatedType<T> annotatedType = processAnnotatedType.getAnnotatedType();
String commandName = annotatedType.getAnnotation(CQRSCommandHandler.class).command().getName();
String handlerName = annotatedType.getJavaClass().getName();
discoveredCommandHandlers.put(commandName, handlerName);
}
}
我正在苦苦挣扎的是我应该如何急切地实例化这个 bean 并将 HashMap
传递给这个 bean。
我可以找到很多示例,例如这个 (http://ovaraksin.blogspot.co.uk/2013/02/eager-cdi-beans.html),它们展示了如何急切地实例化任何具有特定注释的 bean,但是我不知道如何实例化一个特定的 bean 并传递一个HashMap
给这个豆子。
理想情况下,我不希望使用反射来扫描注释。
如何实例化一个特定的 bean 并将 HashMap
传递给该 bean?或者,有没有更好的方法可以在不使用反射的情况下获得相同的结果?
为什么需要急切实例化 bean?
您有两个选择:
- 改为将扩展注入到 bean 中,并在其中使用
HashMap
。
例如
@Inject
public MyAppScopedBean(MyExtension extension) {
this.someHashMap = extension.getHashMap();
}
- 将
HashMap
传递给生产者方法以提供对HashMap
的注入支持。
如果你真的想自己实例化 bean,你实际上是在试图打破 DI 的概念。
如果可以选择运行时扫描,您可能想看看 https://code.google.com/p/reflections/ 它提供了一个简单而强大的 API.
否则看看这个link。 16.10 中的示例非常相似,因为在示例中 bean 中的值是由扩展设置的。您可以调整该示例以将 hashMap 设置到您的应用程序范围的 bean 中。您只需使用像这样的观察者方法
ApplicationScopedBean void processInjectionTarget(
@Observes ProcessInjectionTarget<ApplicationScopedBean> pit) { ...
并在包装的 InjectionTaget 实现中将映射设置到 bean 中。