如何在 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?

您有两个选择:

  1. 改为将扩展注入到 bean 中,并在其中使用 HashMap

例如

@Inject
public MyAppScopedBean(MyExtension extension) {
    this.someHashMap = extension.getHashMap();
}
  1. 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 中。

https://docs.jboss.org/weld/reference/latest/en-US/html/extend.html#_wrapping_an_literal_injectiontarget_literal