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

如何确保Java CDI框架实现将在自定义bean的自定义注入点注入实例?

元昊苍
2023-03-14
  • 我正在使用Weld作为基础CDI框架实现。
  • 我有一个类ClassWithoutControl,它没有一个no-arg构造函数(也就是不是一个有效的Bean)。
  • 我为该类创建了一个自定义Bean。
  • 在触发AfterBeanDiscovery事件时,我通过扩展添加此bean。
  • 当对这个bean调用create(creationalcontext<>ctx)时,我构造了ClassWithoutControl类的一个新实例。
  • 我已经为该自定义bean创建了一组InjectionPoints。
  • 其中一个InjectionPoints是ClassWithControl的字段。

如何确保CDI将注入InjectionPoint所需类型的实例?

换句话说,我如何为一个我没有控制权的类构造一个自定义bean,以使我仍然可以将一个我有控制权的类的实例注入到一个特定的字段中?

    void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager beanManager) {
    final AnnotatedType<ClassWithoutControl> annotatedType = beanManager.createAnnotatedType(ClassWithoutControl.class);
    AnnotatedField<ClassWithoutControl> annotatedField = null;
    for (AnnotatedField<? super ClassWithoutControl> field : annotatedType.getFields()) {
        if ("field".equals(field.getJavaMember().getName()) && ClassWithControl.class.equals(field.getJavaMember().getType())) {
            annotatedField = (AnnotatedField<ClassWithoutControl>) field;
            break;
        }
    }
    final InjectionPoint injectionPoint = beanManager.createInjectionPoint(annotatedField);
    final HashSet<InjectionPoint> injectionPoints = new HashSet<>();
    injectionPoints.add(injectionPoint);
    BiFunction<CreationalContext<ClassWithoutControl>, Bean<ClassWithoutControl>, ClassWithoutControl> creator = (creationalContext, bean) -> {
        final InjectionTarget<ClassWithoutControl> injectionTarget = beanManager.createInjectionTarget(annotatedType);
        ClassWithoutControl instance = new ClassWithoutControl(this.paramater1, this.parameter2);
        injectionTarget.inject(instance, creationalContext);
        injectionTarget.postConstruct(instance);
        return instance;
    };
    customBeanBuilder.setInjectionPoints(injectionPoints).setCreator(creator);
    final BeanAttributes<ClassWithoutControl> beanAttributes = beanManager.createBeanAttributes(annotatedType);
    customBeanBuilder.setBeanAttributes(beanAttributes);
    abd.addBean(customBeanBuilder.build());
}

我知道为什么上面不起作用。NonProducibleInjectionTarget由Weld返回,因为Weld用于创建InjectionTarget的AnnotatedType没有no-args构造函数。然而,我正在寻找一种方法,我可以做到这一点,而不必依赖焊缝的内部实现。我找不到一种方法来欺骗CDI接受我的ClassWithoutControl实例,同时重新训练注入另一个实例的能力。

我查看了https://docs.jboss.org/weld/reference/latest/en-us/html_single/#_wrapping_an_injectiontarget,但我不太明白如何创建这样的包装器。因此,在这个方向上的任何帮助都将被感激。

共有1个答案

巫马瀚漠
2023-03-14

我深入研究了Weld(我当前的CDI实现),看看是否能找到解决这个问题的方法。不幸的是,由于我不控制的类中缺少no-args构造函数,我无法提供InjectionTarget。BeforeBeanDiscovery显示扩展正在添加类的bean。但是,由于它缺少no-args构造函数,因此从未创建过InjectionTarget。

通过在ProcessAnnotatedType过程中包装AnnotatedType,插入一个AnnotatedConstructor,并将其与原始AnnotatedType的构造函数一起返回,我已经尽力解决了这个问题。这是可以做到的,不幸的是AnnotatedConstructor有一个返回原始构造函数的getJavaMember()方法。在我的例子中,构造函数(java-member)不存在,因此无法实例化构造函数的新实例。这是一个死胡同,因为没有其他方法可以获得构造函数的自定义实例。

我现在正在探索字节码操作库,如Byte-Buddy。这将使我能够在运行时添加一个no-args构造函数。对我来说不会有任何影响,因为no-args构造函数的唯一目的是确保CDI将类标记为有效的bean。

 类似资料:
  • 问题内容: 在自定义的Wicket类中,与下面的类似,我使用的是应由Spring注入的服务bean,如通过SpringBean批注定义的(来自wicket- spring项目)。 但是,这是行不通的:NullPointerException失败,因为由于 某种原因Spring尚未注入该bean 。 奇怪的是,我在Wicket页面上使用了与匿名内部类完全相同的Model代码,并且在那里没有问题。 我

  • 我在整个代码中有一堆常量,用于系统的各种可调整属性。我正在将它们全部移动到一个中央文件中。我目前的解决方案是有一个静态加载文件并公开各种getter方法,如下所示: 唯一的问题是,对于我从这个文件中获得的每个常量,我都有一些样板: 我不认为我想使用Spring或类似的东西,因为那看起来更像是boilerplae。我希望使用自定义注释来解决这个问题。我找到了这个教程,但是我真的不能弄清楚如何从注释处

  • 目前,我将辅助注射与命名参数一起使用,如下所示: 这很棒。但是我认为使用字符串作为参数的标识符有点难看。我想做的是以下内容: 所以本质上我想要自定义辅助注释。有办法做到这一点吗?

  • 本文向大家介绍Hibernate Validation自定义注解校验的实现,包括了Hibernate Validation自定义注解校验的实现的使用技巧和注意事项,需要的朋友参考一下 情景:需要对String类型的属性比如description进行验证,验证规则是当description为空时不进行正则校验,description不为空时进行正则校验。上述需求Hibernate Validatio

  • 我需要实现我的自定义DefaultComboxModel。这样做的原因是每次我打电话给 或者 或者 我看到它自动触发一个项目状态更改事件。这会导致一些随机项目自动从列表中选择。这不是我想要的,因为它用随机选择的项目填充可编辑的JTextField。 这是我在使用我的自定义Itemlistener中的Thread.dumpStack()进行调试时看到的stacktrace,它是我在调用上述方法时看到

  • 本文向大家介绍Android 自定义密码输入框实现代码,包括了Android 自定义密码输入框实现代码的使用技巧和注意事项,需要的朋友参考一下 效果 自定义密码输入框,项目的一个界面需求,我把这个自定义的输入框提取出来作为这次内容的题目。 输入前:   输入后:   输入1个字符就红一个圈圈,很简单的效果。 思路 1.自定义EditText。 2.背景为一个外圆环加内实心圆。 3.edittext