我是Struts2框架和EJB的新手。我有一个类LoginDAO
,它实现接口LoginDAOLocal
的checkUser
方法。我不明白为什么在以下场景中我看到了不同的行为:
如果我像下面这样使用EJB (LoginDAO
是无状态会话bean),方法调用可以完美地工作,没有任何错误。
@EJB
private LoginDAOLocal loginDao;
loginDao.checkUser(userName,password);
如果我像下面这样使用Struts2,它会为方法调用提供一个空指针异常。
public class LoginAction extends ActionSupport {
// Getters setters for userName and password)
private LoginDAOLocal loginDao;
loginDao.checkUser(this.userName,this.password);
}
如果我使用一个简单的Java应用程序(没有EJB或Struts2),方法调用将创建一个编译时错误,说loginDao未初始化
public static void main(String[] args) {
LoginDAOLocal loginDao;
loginDao.checkUser(userName,password);
}
谁能解释一下为什么这种不同的行为?
不要太深入Java EE规范:EJB是由存在于J2EE服务器(JBoss Websphere等)中的EJB容器管理的。容器控制bean的生命周期,并负责根据应用程序的需要创建/销毁bean。
当用完容器(简单的java应用程序)时,您的bean将不会初始化,并且您没有JNDI上下文来从中获取bean,即使您向字段成员添加@EJB注释。
我们可以说有两种方法来管理bean,使用容器(由容器管理)或使用另一个组件(由servlet、侦听器或过滤器管理)。
使用由容器管理的组件,容器注入引用。例如:
@WebServlet("/test")
public class MyServlet extends HttpServlet {
@Resource(lookup = "jdbc/TestDS")
private DataSource testDS;
}
相比之下,由bean管理的组件,例如:
@Namespace("/User")
@ResultPath(value = "/")
@Result(name = "success", location = "pages/login.jsp")
public class LoginAction extends ActionSupport {
}
由过滤器org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
管理。后者应该负责执行依赖项注入。例如,Spring负责注入所有必要的依赖项。