[英]Correct CDI annotations with Jersey/Glassfish
由於我一直在努力尋找有關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
等問題,並在博客文章和許多資源,有他們自己的人解釋。
在澤西島/格拉斯菲什進行注射操作時,正確的普通CDI注釋是什么?
由於這是一項服務,因此可以使用@Stateless
注釋DefaultBookDAO
。
然后,您需要一個實現AbstractBinder
類的附加類。
對於您的情況,應如下所示:
import org.glassfish.hk2.utilities.binding.AbstractBinder;
public class MyApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(DefaultBookDAO.class).to(BookDAO.class);
}
}
您必須在擴展ResourceConfig
的類中注冊該類,如下所示:
@ApplicationPath("/bookstore")
public class BookStore extends ResourceConfig {
public BookStore() {
register(new MyApplicationBinder());
this.packages("my.bookstore.resource");
}
}
然后@Inject
應該工作。
也可以看看:
對我來說,您似乎沒有將beans.xml文件放入應用程序中。 對於Glassfish 4(通常是Java EE 7),不需要此文件,但是,如果省略它,則僅考慮使用范圍注釋進行注釋的bean。 因此,由於DefaultBookDAO未被任何批注標記,因此CDI不會將其視為注射候選對象。
您有2個選項可以修復它,並使CDI機制考慮DefaultBookDAO:
@Dependent
注釋放在DefaultBookDAO類上-這不會更改其范圍,因為@Dependent
是默認范圍,但會使CDI考慮此類 bean-discovery-mode="all"
的值創建beans.xml文件 我認為,第一種選擇是更清潔-您可以輕松地分離可以注入和不能注入的代碼。 但是,如果您想通過省略不必要的注釋來提高生產率,請選擇第二個選項。 它更加復雜,但是每個模塊只需執行一次。
請參閱此關於Java EE 7中bean.xml的Oracle博客文章以及默認行為(如果省略)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.