【问题标题】:CDI: Injecting single instance works, but injecting Instance<> does not. Why?CDI:注入单个实例有效,但注入 Instance<> 无效。为什么?
【发布时间】:2017-08-16 11:56:56
【问题描述】:

我正在尝试借助 CDI 注入来实现某种“插件功能”。但是我遇到了一些麻烦,我想我可能会从我的“堆垛机”同伴那里得到一些外部观点:-)

到目前为止,我已经知道这样的事情了:

@Inject 
@ScoringModule("AGE")
private AgeModule ageModule;

@Inject 
@ScoringModule("CUSTOMER_TYPE")
private CustomerTypeModule customerTypeModule;

当我“运行”它时,两个字段都会被注入适当的实例。但是当我尝试像这样更“动态”地注入它们时:

@Inject @Any
private Instance<CustomerScoringModule> scoringModuleInstance;

CustomerScoringModule module = scoringModuleInstance.select(new ScoringModuleLiteral("AGE")).get();

然后我会得到这样的异常:

org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type CustomerScoringModule with qualifiers @Any @ScoringModule

这对我来说似乎很奇怪,因为 CDI 清楚地“知道”我感兴趣的实例,因为直接注入到类型化字段中是有效的。所以我假设它一定与预选赛有关? CDI 不知何故“看到”了这两个实例,但决定它们都不适合我的注入请求?会这样吗?

有什么“明显”的事情让我想到我可能在这里做错了吗?我第一次尝试使用 CDI,我有可能(甚至很可能)在某处做一些愚蠢的事情 :-)

感谢任何帮助或提示,并提前非常感谢!

下面我将附上限定符和注释文字等的“周围”类以供参考。

两个模块都实现的 CustomerScoringInterface:

package de.otto.cccs.customerscoring.modules;

import de.otto.cccs.customerscoring.modules.vo.ScoringModuleResponseVO;
import de.otto.cccs.customerscoring.valueobjects.webservice.ScoringRequestVO;

public interface CustomerScoringModule {
    public ScoringModuleResponseVO process(ScoringRequestVO inputVO);
}

两个模块实现之一(它们现在只是虚拟实现,唯一的区别是 process() 方法中的 log.info() 输出,这就是为什么我在这里只包括其中一个):

package de.otto.cccs.customerscoring.modules;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

import de.otto.cccs.customerscoring.modules.qualifiers.ScoringModule;
import de.otto.cccs.customerscoring.modules.vo.ScoringModuleResponseVO;
import de.otto.cccs.customerscoring.valueobjects.webservice.ScoringRequestVO;
import lombok.extern.log4j.Log4j2;

@Log4j2
@Stateless
@LocalBean
@ScoringModule("AGE")
public class AgeModule implements CustomerScoringModule {

    public AgeModule() {
        super();
    }

    @Override
    public ScoringModuleResponseVO process(ScoringRequestVO inputVO) {
        log.info("processed AGE_MODULE");

        return new ScoringModuleResponseVO();
    }

}

@ScoringModule 限定符:

package de.otto.cccs.customerscoring.modules.qualifiers;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

@Qualifier
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ScoringModule {
    String value();
}

还有AnnotationLiteral:

package de.otto.cccs.customerscoring.modules.qualifiers;

import javax.enterprise.util.AnnotationLiteral;

public class ScoringModuleLiteral extends AnnotationLiteral<ScoringModule> implements ScoringModule {

    private static final long serialVersionUID = 1L;
    private String value;

    public ScoringModuleLiteral(String value) {
        this.value = value;
    }

    @Override
    public String value() {
        return this.value;
    }
}

最后是我的空 beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

【问题讨论】:

  • 我可以看到直接注入使用确切的 bean 类型而不是接口。 @Inject @ScoringModule("AGE") CustomerScoringModule ageModule 有效吗?
  • 这是一个公平的观点和一个很好的问题。我现在不在办公室,但明天会测试并报告。感谢您的反馈。
  • 该死...不能等到明天,必须知道它是否有效:-) 刚刚通过 TeamViewer 远程签入并对其进行了测试,当我使用类似的界面时它不起作用你建议。问题是,这告诉我们什么?
  • 接口是否也需要某种限定符?我尝试在 CustomerScoringModule 界面中添加一个 @ScoringModule("") ,但这也不起作用。
  • 它告诉我们什么 - 我不知道。这是一个起点。应用程序是如何打包的?所有这些类都在同一个罐子里吗?会不会是 CDI(或 EJB ???)没有将 CustomerScoringModule 识别为业务本地接口 - 所以它不包含在 CDI bean 类型中?如果您忽略 @LocalBean(如果可能的话)会怎样?

标签: jakarta-ee cdi payara


【解决方案1】:

我最终将模块从 EJB 更改为纯 Java 类,我所有的麻烦都消失了。

我并不真正需要模块是 EJB,我只是在开始时错误地认为它们必须通过 CDI 注入,现在情况不再是这样了(旧的 J2EE 版本确实如此)

感谢您的反馈!

【讨论】:

  • 现代CDI哲学还可以,比古代进步大,f.e.很吸引人。对于弹簧用户。编辑:许多知识来源混合了 J2EE、spring 等。我个人的补救措施是干净的 CDI
猜你喜欢
  • 1970-01-01
  • 2016-02-08
  • 2013-06-20
  • 2016-11-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多