我正在为JavaEE7中的学习CDI设置基本环境。我有以下代码来启动Weld
。只是一个启动和关闭。
package com.anshbansal;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
public class Main {
public static void main(String[] args) {
Weld weld = new Weld();
WeldContainer container = weld.initialize();
weld.shutdown();
}
}
我正在控制台上关注。
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/Softs/Programming/Java/Java%20JARs/JBoss%20Weld-2.0.3/jar/weld-se.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/Softs/Programming/Java/Java%20JARs/JBoss%20Weld-2.0.3/jar/weld-servlet.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory]
[main] INFO org.jboss.weld.Version - WELD-000900 2.0.3 (Final)
[main] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
有问题的行是WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
。这只是意味着依赖注入不起作用。但我不确定是什么问题。我在weld-se.jar
添加了CLASSPATH
。我甚至没有达到初始化对象的意义,为什么会出现这个问题呢?
Weld的官方文档也提供了我在阅读this answer后得到的相同代码。书中使用了相同的代码" Beginning Java EE 7"安东尼奥·贡萨尔维斯"。我已经验证了this github location的导入。因此,如果我使用了正确的类路径并且没有创建任何对象,那么为什么会出现这个问题呢?
答案 0 :(得分:6)
您可以在Java SE中学习CDI。
在Java EE中使用CDI时,您显然需要一个Java EE容器,一个使用main
方法的普通旧应用程序。
Weld只是告诉您交易不可用(因为您没有在EE容器中运行),因此任何与交易相关的CDI功能都将被禁用。
依赖注入 将在您的情况下工作,只要您不尝试注入任何Java EE对象或使用任何需要Java EE容器的CDI功能。
答案 1 :(得分:2)
运行Java EE应用程序需要应用程序服务器(或容器)。对于运行企业应用程序所需的不同服务(安全性,消息传递,事务等等)的集成,此容器使您的生活变得非常简单。
如果您不使用应用程序服务器(就像您在示例中所做的那样),您必须自己进行此集成(即构建自己的服务器)。自服务器存在以来,这是一项非常艰苦而无用的任务。
您在问题中显示的代码是当您不想要或可以使用容器时,如何使用Weld的专有部分手动启动CDI容器。
如果你仔细阅读安东尼奥的书,你会在页面xxxiv 的'下载并运行代码'一节中看到它,表明你需要部署你的Glassfish 4上的代码,它是开源Java EE 7服务器之一(另一个是JBoss Wildfly)
本书的附录A (第539页)以非常精确的方式描述了如何设置环境以运行书籍示例和简单的Java EE应用程序。请按照本部分的说明进行操作,您将看到开发和部署Java EE 7应用程序非常简单。
答案 2 :(得分:2)
要设置学习CDI环境,您只需要一个CDI实现,例如Weld参考实现;你不需要Java EE容器。
简单的方法是在pom.xml
中创建一个具有依赖关系的maven项目:
(确保在运行java应用程序之前在beans.xml
目录中创建一个空文件或最小META-INF
文件。如果你去maven,你可以在META-INF
中创建src/main/resources
}目录)
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>2.3.4.Final</version>
</dependency>
这是申请表:
public class CdiApplication {
private Weld weld;
private WeldContainer container;
private BookService bookService;
private void init() {
weld = new Weld();
container = weld.initialize();
BookService = container.instance().select(BookService.class).get();
}
private void start() {
Book book = bookService.createBook("My title", "My description", 23.95);
System.out.println(book);
}
private void shutdown() {
weld.shutdown();
}
public static void main(String[] args) {
CdiApplication application = new CdiApplication();
application.init();
application.start();
application.shutdown();
}
}
Book
类:
public class Book { // Book is a POJO
private String title;
private String description;
private double price;
private String id; // ISBN or ISSN
private Date instanciationDate;
public Book() { // default constructor
}
public Book(String title, String description, double price) {
this.title = title;
this.description = description;
this.price = price;
// the BookService is responsible to set the id (ISBN) and date fields.
}
// setters and getters
// toString method
}
BookService
类创建一本书并使用注入的NumberGenerator
设置其实例日期和身份证(ISBN):
public class BookService {
@Inject
private NumberGenerator numberGenerator;
private Date instanciationDate;
@PostConstruct
private void setInstanciationDate() {
instanciationDate = new Date();
}
public Book createBook(String title,
String description, double price) {
Book book = new Book(title, description, price);
book.setId(numberGenerator.generateNumber());
book.setDate(instanciationDate);
return book;
}
}
在servlet环境中,servlet容器将负责引导CDI,这意味着你必须部署你的Web应用程序&#34;在Java EE容器上,例如Tomcat或Wildfly。
答案 3 :(得分:0)
即使您错过了 test / resource / META-INF 文件夹中的 beans.xml 文件,也会出现此问题。\
确保将beans.xml文件维护为 Context and Dependency injection 的必需文件。