使用Jersey/Glassfish实现java正确的CDI注释
由于我正在努力编写关于CDI的文档,我希望这个问题能够成为在Jersey/Glassfish中使用正确CDI注释的有用资源
假设我们有一个应用程序BookStore
:
package my.bookstore;
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
@ApplicationPath("/bookstore")
public class BookStore extends ResourceConfig {
public BookStore() {
this.packages("my.bookstore.resource");
}
}
我们希望通过RESTful服务访问Book
实体:
package my.bookstore.entity;
public class Book {
public String isbn;
public String title;
public String author;
public Book(String isbn, String title, String author) {
this.isbn = isbn;
this.title = title;
this.author = author;
}
}
因此,我们需要一个DAO
来访问数据存储:
package my.bookstore.dao;
import my.bookstore.entity.Book;
import java.util.List;
public interface BookDAO {
public List<Book> getAllBooks();
}
及其实施:
package my.bookstore.dao;
import my.bookstore.entity.Book;
import java.util.List;
import java.util.ArrayList;
public class DefaultBookDAO implements BookDAO {
public List<Book> getAllBooks() {
List<Book> bookList = new ArrayList<>();
list.add(new Book("1234", "Awesome Book", "Some Author"));
return bookList;
}
}
然后我想将DefaultBookDAO
注入RESTful服务:
package my.bookstore.resource;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/books")
public class BookResource {
@Inject
BookDAO dao;
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Book> getBooks() {
return this.dao.getAllBooks();
}
}
现在,在部署应用程序时,我得到:
Unsatisfied dependencies for type BookDAO with qualifiers @Default
因为我需要让CDI意识到这一点;但是怎么做呢?我尝试了各种组合@Named
、@Default
、@Model
、@Singleton
、@Stateless
,许多资源(如问题和博客文章)都有自己的解释
在Jersey/Glassfish中,要使用什么正确、简单的CDI注释使此注入工作
# 1 楼答案
对我来说,似乎你没有放豆子。将xml文件导入到应用程序中。对于GlassFish4(通常是JavaEE7),不需要这个文件,但是,如果省略它,则只考虑使用范围注释注释的bean。因此,由于DefaultBookDAO没有被任何注释标记,所以CDI不认为它是注入的候选对象
您有2个选项来修复它,并使CDI机制考虑Debug ToBooDa:
bean-discovery-mode="all"
在我看来,第一种选择是更干净的——您可以很容易地将可以注入的代码和不能注入的代码分开。但是,如果您想通过省略不必要的注释来提高生产率,请使用第二个选项。它更复杂,但每个模块只需执行一次
请参阅this oracle blog post关于bean的内容。JavaEE7中的xml以及省略时的默认行为
# 2 楼答案
因为它是一个服务,所以您可以用
@Stateless
注释您的DefaultBookDAO
然后需要一个额外的类来实现
AbstractBinder
类您的案例应该是这样的:
您必须在扩展
ResourceConfig
的类中注册该类,如下所示:那么
@Inject
应该可以工作了另请参见: