简体   繁体   English

使用CDI注入接口实现

[英]Inject interface implementation with CDI

I can't get a very simple point on CDI! 我对CDI一点都不了解!

I have these classes in my application: 我的应用程序中包含以下类:

public class CarrelloController extends AbstractController {

    @Inject CarrelloService carrelloService;

    ...
}


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

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

However, I am getting the following error, after deploying: 但是,部署后出现以下错误:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type CarrelloService with qualifiers @Default at injection point [BackedAnnotatedField] @Inject @Default it.footballove.web.controller.CarrelloController.carrelloService at it.footballove.web.controller.CarrelloController.carrelloService(CarrelloController.java:0) org.jboss.weld.exceptions.DeploymentException:WELD-001408:在注入点[BackedAnnotatedField]带有限定符@Default的CarrelloService类型的依赖项未满足@Inject @Default it.footballove.web.controller.CarrelloController.carrelloService处在它上。footballove.web .controller.CarrelloController.carrelloService(CarrelloController.java:0)

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

I get that only using an interface. 我只能使用一个接口。 Abstract class instead makes no problem! 相反,抽象类没有问题!

Why? 为什么?

This is the way that EJBs work with CDI. 这就是EJB与CDI协同工作的方式。 The CDI bean types of an EJB are given by the business interface of the EJB, not by the implementation class. EJB的CDI bean类型是由EJB的业务接口给定的,而不是由实现类给定的。 The business interface may be explicitly declared with a @Local annotation. 可以使用@Local注释显式声明业务接口。

In your case, the business interface defaults to the one and only declared interface CarelloDataProvider . 在您的情况下,业务接口默认为一个且仅声明的接口CarelloDataProvider So there really is no CDI bean of type CarelloService . 因此,实际上没有CarelloService类型的CDI bean。

Suggestion: 建议:

Rename your EJB class to CarelloServiceImpl and factor out an interface CarelloService containing the extra methods you need in CarelloController . 将您的EJB类重命名为CarelloServiceImplCarelloServiceImpl出一个接口CarelloService其中包含您在CarelloController需要的CarelloController方法。

@Stateless
public class CarelloServiceImpl implements CarelloService {
}

public interface CarelloService extends CarelloDataProvider {
}

Or just reconsider your design - usually, when you need to access an implementation method not contained in an interface, this is a symptom of mismatched abstractions. 或者只是重新考虑您的设计-通常,当您需要访问接口中未包含的实现方法时,这是抽象不匹配的征兆。

i've hit the same problem, following scenario: 在以下情况下,我遇到了相同的问题:

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

with following structure: 具有以下结构:

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

and finally the implementation to use for injetion: 最后是用于注入的实现:

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

this didn't work and the WELD exception state above has been thrown. 这不起作用,并且上面的WELD异常状态已抛出。 I've tried to annonate the classes with @Named, @Qualifier, @Default... but non has worked. 我试图用@ Named,@ Qualifier,@ Default ...来标注类,但非奏效了。

In order to make the injection work with an abstract class, it is required to implement explicitly the interface in the service bean: 为了使注入与抽象类一起工作,需要在服务bean中显式实现接口:

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

Simple said: implement explicit the interface you want to injection into the implementation (in addition to the abstract class). 简单地说:实现要注入到实现中的显式接口(除了抽象类)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM