2015-09-30 64 views
0

由於我在關於CDI的文檔方面掙扎不已,我希望這個問題能夠成爲在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和許多資源,如問題和博客文章都有他們自己的解釋。

什麼是在Jersey/Glassfish中使用這個注射工作的正確的純CDI註釋?

+0

什麼版本的玻璃魚? –

+0

@JohnAment Glassfish 4.1 –

回答

0

對我來說,似乎你沒有把beans.xml的文件到您的應用程序。對於Glassfish 4(通常使用Java EE 7),該文件不是必需的,但是,如果忽略它,則只考慮使用範圍註釋註釋的bean。因此,由於DefaultBookDAO沒有任何註釋標記,它不被CDI認爲是注射的候選者。

您有2個選項來解決它,使CDI機制考慮DefaultBookDAO:

  • @Dependent註釋上DefaultBookDAO類 - 這不會改變它的範圍,因爲@Dependent是默認的範圍,反而會使CDI來考慮該類
  • 在任何META-INF或WEB-INF(對於Web應用程序)創建beans.xml的文件與bean-discovery-mode="all"

的價值在我看來,第一個選項更清潔 - 您可以輕鬆分離可以注入和不能注入的代碼。但是,如果您想通過省略不必要的註釋來提高生產力,請使用第二個選項。它比較複雜,但每個模塊只能執行一次。

請參閱this oracle blog post有關使用Java EE 7的beans.xml和默認行爲如果忽略。

0

由於這是一項服務,您可以使用@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應該工作。

參見:

+0

我真的需要一個活頁夾嗎?澤西不應該自動尋找「BookDAO」的實現來注入? –

+0

錯誤消息'帶有限定符@默認值的BookDAO類型的不滿意依賴關係'提示提示CDI被用作依賴注入機制。您的建議與HK2機制有關,顯然Jersey也支持該機制,但未在Java EE標準中指定,並且未用於最近Glassfish v4的標準設置。 – OndrejM