[英]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.