关于EJB3的DI一处注意

今天在学习EJB3的时候发现了一个问题。我所使用的环境是GLASSFISH V3. 实现了一个简单的stateless session bean作为练习如下:

business interface 如下:
@Local
public interface FirstLocalSessionBeanInterface {

    public String getHelloMessage();
    
}


Session bean 如下:
@Stateless
public class FirstLocalSessionBean implements FirstLocalSessionBeanInterface {

    public String getHelloMessage() {
        return "Hello! This is a Local StateLessSessionBean!";
    }    
}


然后在同一个ear项目里建立web project来调用该EJB, 我使用JSP调用一个POJO类, 原本打算在该POJO类里直接注入EJB, 代码如下:
public class LocalSessionBeanDelegate {
    @EJB
    private FirstLocalSessionBeanInterface bean;
    
    public String getEJBMessage(){
        return bean.getHelloMessage();
    }


我在jsp中调用该类的时候,却总是报bean空指针,这说明@EJB并没有成功的注入该属性。

后来我在java.net的glassfish forum上找到了答案。原来GLASSFISH下的EJB资源注入只支持受容器管理的对象,如EJB,SERVLET,JSF等等。而对于普通POJO是不支持的。要在这些POJO里使用EJB,还得使用传统的JNDI查询方式。

我之后尝试了一下servlet的情形,代码如下:
public class LocalSessionBeanServlet extends HttpServlet {
   
    @EJB
    private FirstLocalSessionBeanInterface bean;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        System.out.println(bean.getHelloMessage());
        request.setAttribute("message", bean.getHelloMessage());
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
        request.getRequestDispatcher("./localBeanTest.jsp").forward(request, response);
    } 

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
        request.getRequestDispatcher("./localBeanTest.jsp").forward(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}


经测试,该代码可以正常的实现EJB注入。

经过该例,发现在GLASSFISH下EJB注入只能在容器管理的组件中实现。我不知道这是否是EE规范中得到规定还是GLASSFISH的实现是这样要求。哪位大虾可以告知一下,不胜感谢。

注:之后查阅了JEE5规范,发现确实在其中有对于这方面的规定。JEE支持DI的组件主要有以下几种:

Servlet:  servlets/servlet filters/event listeners

JSP: tag handlers/tag library event listeners

JSF: scoped managed beans

JAX-WS: service endpoints/handlers

EJB; beans/interceptors

Java EE platform: main class (static)/login callback handler

你可能感兴趣的:(bean,jsp,servlet,ejb,Glassfish)