繁体   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