简单单例EJB示例
我正在学习EJB并编写了一个使用GlassFish 4的示例程序,但由于某些原因,它无法正常工作。简单单例EJB示例
的index.jsp:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ page import="javax.ejb.EJB" %>
<%@ page import="ejbtest.utility.Utility" %>
<%@ page import="ejbtest.action.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>EJB Test</title>
</head>
<body>
<%
try {
Utility utility = new Utility();
out.println("count: " + utility.getCount() + "<br/><br/>");
Trigger1 trigger1 = new Trigger1();
out.println("trigger1 count: " + trigger1.getTriggerCount());
} catch (NullPointerException npe) {
out.println("Nullpointer caught");
}
%>
</body>
</html>
Utility.java:
package ejbtest.utility;
import javax.ejb.Singleton;
import javax.ejb.Startup;
@Startup
@Singleton
public class Utility {
int count;
public Utility() throws NullPointerException {
count = 0;
count++;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
Trigger1.java:
package ejbtest.action;
import ejbtest.utility.Utility;
import javax.faces.bean.ApplicationScoped;
import javax.inject.Inject;
@ApplicationScoped
public class Trigger1 {
@Inject
Utility utility;
public Integer getTriggerCount() {
return utility.getCount();
}
}
不希望输出:
数:1
空指针抓住
首先,你在标准JVM中启动你的EJB。但是EJB只能存在于EJB容器中。当您使用main方法启动应用程序时,所有EJB注释都会被忽略。您需要像Glassfish或JBoss这样的应用程序服务器来测试您的应用程序。
这里您改进例如:
Trigger1.java
package ejbtest.action;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import ejbtest.utility.Utility;
@Stateless
public class Trigger1 {
@EJB
private Utility utility;
public Integer getTriggerCount() {
return utility.getCount();
}
}
Utility.java
package ejbtest.utility;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
@Singleton
public class Utility {
int count = 0;
@PostConstruct
public void init() {
count++;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
的index.jsp
<%@page import="ejbtest.action.Trigger1"%>
<%@page import="ejbtest.utility.Utility"%>
<%@page import="javax.naming.InitialContext"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>EJB Test</title>
</head>
<body>
<%
InitialContext ic = new InitialContext();
Utility utility = (Utility) ic.lookup("java:module/Utility");
out.println("count: " + utility.getCount() + "<br/><br/>");
Trigger1 trigger1 = (Trigger1) ic.lookup("java:module/Trigger1");
out.println("trigger1 count: " + trigger1.getTriggerCount());
%>
</body>
</html>
我想你只能在其他Session Beans
或Message-Driven Beans
注入EJB
。在你的代码中,你尝试将它们注入简单的java类。你可以在JNDI lookup
的java类中引用它们。
如果你的类Trigger1
和Trigger2
不在同一(Java EE
)应用程序作为Utility
的Bean,那么你需要Remote
访问,因此接口视图。然后,您可以按如下方式访问Singleton
Bean:https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project。
如果您的Trigger1
和Trigger2
类与您的Utility
Bean具有相同的属性,那么您已经提供的本地无界面视图就足够了。像你一样,你可以通过Injection
访问Singleton
Bean,但是你必须让你的类Session
Beans(最好是无状态的)。然后你应该再次通过JNDI lookup
从你的主要方法访问它们。
您能不能告诉我什么代码去查因为我对这个术语还是比较陌生的,所以我把它付诸实践 – ThreaT
我在Tomcat 7和GlassFish 4内部作为JSP scriptlet而不是主要类尝试了它,但我得到了同样的结果。 .. – ThreaT
显示scriplet代码。如果你这样做新的Trigger1(),所以它是错误的。由您自己创建的对象会创建外部EJB容器并忽略EJB注释。您的Trigger1对象必须由EJB容器创建。 – Fireworks
代码已更新,仍然通过JSP获得NullPointerException – ThreaT