【问题标题】:CDI will not work with implicit @Dependent scope, unsatisfied injection point compile time errorCDI 不适用于隐式 @Dependent 范围,不满足注入点编译时错误
【发布时间】:2015-05-07 00:18:26
【问题描述】:

容器是 Glassfish 4.1

我现在对 CDI 有一个非常奇怪的问题。如果我不注释我的NumberGenerator 服务@Dependent,那么当我运行应用程序时,我会不断收到不满意的注入点错误。但是,如果我明确地注释我的NumberGenerator 实现,那么一切都会奏效。总之,如果我想使用默认作用域@Dependent 进行依赖注入,我必须明确指定它。

 public interface NumberGenerator {
    String generateNumber();  
 }

NumberGenerator的第一个实现

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;

@ThirteenDigits
@Dependent
public class IsbnGenerator implements NumberGenerator {

    @Inject
    private Logger logger;

    @Override
    public String generateNumber() {
        String isbn = "13-84356-" + Math.abs(new Random().nextInt());
        logger.log(Level.INFO, "Generated ISBN : {0}", isbn);
        return isbn;
    }

}

NumberGenerator的第二种实现

import java.util.Random;
import java.util.logging.Logger;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;

@EightDigits
@Dependent
public class IssnGenerator implements NumberGenerator {

    @Inject
    private Logger logger;

    @Override
    public String generateNumber() {
        String issn = "8-" + Math.abs(new Random().nextInt());
        logger.info("Generated ISSN : " + issn);
        return issn;
    }

}

这是NumberGenerator 将被注入的地方

import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.interceptor.Interceptors;


@Dependent
public class BookService {

    @Inject 
    @EightDigits
    private NumberGenerator numberGenerator;

    public Book createBook(String title, float price, String description) {
        Book book = new Book(title, price, description);
        book.setNumber(numberGenerator.generateNumber());
        return book;
    }

}

最后,BookService 被注入到这个 JSF 托管 bean 中以创建一个 Book 实例。

import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.inject.Named;


@Named
@Dependent /* if I leave this out, then this bean will not display 
              the book instance properties on the JSF page, I just see
              a blank screen, but when I add this @Dependent annotation
              the JSF page displays the dummy content below.
           */
public class MyBean {

    @Inject
    private BookService bookService;

    public Book getBook() {
    return bookService.createBook("Dummy Title", 21.05f, "Dummy Description");
    }

}

如您所见,每次需要 DI 时,我都必须使用 @Dependent 作为默认范围。现在,我将带有限定符 @EightDigitsIssnGenerator 注入到 BookService 类中,如果我从 IssnGenerator 中删除 @Dependent,我会收到此编译错误。

 Unsatisfied dependencies for type NumberGenerator with qualifiers @EightDigits at injection point [BackedAnnotatedField] @Inject @EightDigits private BookService.numberGenerator

感谢您的任何建议。

【问题讨论】:

  • 没人愿意帮忙吗? :(

标签: dependency-injection glassfish cdi managed-bean glassfish-4.1


【解决方案1】:

如果您没有指定 META-INF/beans.xml 文件,这似乎是您的情况,您会得到一个隐式 bean 存档 (see CDI-1.1 §12.1)。

隐式 bean 归档中,只有具有 bean 定义注释的 bean 才会被 CDI 引擎发现。

任何范围都是 bean 定义注释 (see CDI-1.1 §2.5)。这就是为什么如果你添加一个范围,比如@Dependent,你的 bean 会被 CDI 发现并且你没有不满足的依赖错误。

@Dependent 是默认作用域的事实与此处无关,因为没有任何作用域,您的 bean 根本不会被发现。

如果您添加一个 META-INF/beans.xml 文件并将 bean-discovery-mode 设置为 all,那么您将获得一个显式 bean 存档,这意味着您的存档中的所有 bean 都将被发现并且将默认具有@Dependent 范围。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多