【问题标题】:Inject interface implementation with CDI使用 CDI 注入接口实现
【发布时间】:2016-07-25 14:13:46
【问题描述】:

我对 CDI 没有一个非常简单的观点!

我的应用程序中有这些类:

public class CarrelloController extends AbstractController {

    @Inject CarrelloService carrelloService;

    ...
}


@Stateless
public class CarrelloService implements CarrelloDataProvider {
   ...
}

public interface CarrelloDataProvider {
    public Oggetto getSomething(String foo);
}

但是,我在部署后收到以下错误:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: 带有限定符的 CarrelloService 类型的依赖关系不满足 @Default 在注入点 [BackedAnnotatedField] @Inject @Default it.footballlove.web.controller.CarrelloController.carrelloService 在 it.footballlove.web.controller.CarrelloController.carrelloService(CarrelloController.java:0)

在 org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359) 在 org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281) 在 org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134) 在 org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155) 在 org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518) 在 org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68) 在 org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66) 在 org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60) 在 org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745) 异常 0 :

我只使用一个界面。抽象类反而没有问题!

为什么?

【问题讨论】:

  • 我不明白你的意思是什么我只能使用界面来理解。抽象类反而没有问题!。您发布的代码显示注入点的类型是类CarrelloService,而不是它的接口CarrelloDataProvider。你为什么要这样做?
  • 因为在那种情况下我知道我需要那个具体的具体实现。如果我将 CarrelloDataProvider 定义为一个抽象类并让服务扩展它,我不会收到任何错误。

标签: java jakarta-ee dependency-injection cdi inject


【解决方案1】:

这就是 EJB 与 CDI 一起工作的方式。 CDI bean types of an EJB 由 EJB 的业务接口给出,而不是由实现类给出。可以使用@Local 注释显式声明业务接口。

在您的情况下,业务接口默认为唯一声明的接口CarelloDataProvider。所以真的没有 CarelloService 类型的 CDI bean。

建议:

将您的 EJB 类重命名为 CarelloServiceImpl 并分解出一个接口 CarelloService,其中包含您在 CarelloController 中需要的额外方法。

@Stateless
public class CarelloServiceImpl implements CarelloService {
}

public interface CarelloService extends CarelloDataProvider {
}

或者只是重新考虑您的设计 - 通常,当您需要访问不包含在接口中的实现方法时,这是抽象不匹配的症状。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,如下场景:

    public interface Importer() { ..... }
    

    结构如下:

    public abstract class DefaultImporter implements Importer { // some default methods }
    

    最后是用于注入的实现:

    public class DefaultFileImporter extends DefaultImporter implements Serializable { ...}
    

    这不起作用,上面的 WELD 异常状态已被抛出。我尝试使用@Named、@Qualifier、@Default... 对这些类进行 annonate... 但没有成功。

    为了使注入与抽象类一起工作,需要在服务bean中显式实现接口:

    public class DefaultFileImporter extends DefaultImporter implements Importer, Serializable { ...}
    

    简单说:将要注入的接口显式地实现(除了抽象类)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      • 2016-09-17
      • 2015-07-05
      • 2019-04-09
      • 1970-01-01
      • 2018-04-11
      • 2021-03-20
      相关资源
      最近更新 更多