CDI 将无法使用隐式@Dependent 范围,未满足的注入点编译时错误
CDI will not work with implicit @Dependent scope, unsatisfied injection point compile time error
容器是 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
作为默认范围。现在,我将带有限定符 @EightDigits
的 IssnGenerator
注入 BookService
class,如果我从 IssnGenerator
中删除 @Dependent
, 我收到这个编译错误。
Unsatisfied dependencies for type NumberGenerator with qualifiers @EightDigits at injection point [BackedAnnotatedField] @Inject @EightDigits private BookService.numberGenerator
感谢您的任何建议。
如果您没有指定 META-INF/beans.xml
文件(这似乎是您的情况),您将得到一个 隐式 bean 存档 (see CDI-1.1 §12.1)。
在隐式 bean 存档 中,CDI 引擎只会发现具有 bean 定义注释 的 bean。
任何作用域都是一个 bean 定义注解 (see CDI-1.1 §2.5)。这就是为什么如果你添加一个范围,比如 @Dependent
,你的 bean 会被 CDI 发现并且你没有不满足的依赖错误。
@Dependent
是默认范围这一事实与此处无关,因为没有任何范围,您的 bean 就不会被发现。
如果您添加 META-INF/beans.xml
文件并将 bean-discovery-mode
设置为 all
,那么您会得到一个 显式 bean 存档 ,这意味着您存档中的所有 bean 都将被发现,并且默认情况下将具有 @Dependent
范围。
容器是 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
作为默认范围。现在,我将带有限定符 @EightDigits
的 IssnGenerator
注入 BookService
class,如果我从 IssnGenerator
中删除 @Dependent
, 我收到这个编译错误。
Unsatisfied dependencies for type NumberGenerator with qualifiers @EightDigits at injection point [BackedAnnotatedField] @Inject @EightDigits private BookService.numberGenerator
感谢您的任何建议。
如果您没有指定 META-INF/beans.xml
文件(这似乎是您的情况),您将得到一个 隐式 bean 存档 (see CDI-1.1 §12.1)。
在隐式 bean 存档 中,CDI 引擎只会发现具有 bean 定义注释 的 bean。
任何作用域都是一个 bean 定义注解 (see CDI-1.1 §2.5)。这就是为什么如果你添加一个范围,比如 @Dependent
,你的 bean 会被 CDI 发现并且你没有不满足的依赖错误。
@Dependent
是默认范围这一事实与此处无关,因为没有任何范围,您的 bean 就不会被发现。
如果您添加 META-INF/beans.xml
文件并将 bean-discovery-mode
设置为 all
,那么您会得到一个 显式 bean 存档 ,这意味着您存档中的所有 bean 都将被发现,并且默认情况下将具有 @Dependent
范围。