簡體   English   中英

使用Jersey / Glassfish糾正CDI批注

[英]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考慮此類
  • 在META-INF或WEB-INF(對於Web應用程序)中使用bean-discovery-mode="all"的值創建beans.xml文件

我認為,第一種選擇是更清潔-您可以輕松地分離可以注入和不能注入的代碼。 但是,如果您想通過省略不必要的注釋來提高生產率,請選擇第二個選項。 它更加復雜,但是每個模塊只需執行一次。

請參閱關於Java EE 7中bean.xml的Oracle博客文章以及默認行為(如果省略)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM