天天看點

【Spring注解驅動開發】面試官:如何将Service注入到Servlet中?朋友又栽了!!

如何實作将Service注入到Servlet中??

這裡,我們列舉兩種解決方法(推薦使用第二種)

方法一:

直接重寫Servlet的Init()方法,代碼如下:

public void init(ServletConfig servletConfig) throws ServletException {
    ServletContext servletContext = servletConfig.getServletContext();
    WebApplicationContext webApplicationContext = WebApplicationContextUtils
            .getWebApplicationContext(servletContext);
    AutowireCapableBeanFactory autowireCapableBeanFactory = webApplicationContext
            .getAutowireCapableBeanFactory();
    autowireCapableBeanFactory.configureBean(this, BEAN_NAME);
}      

這裡的BEAN_NAME即為我們需要注入到Spring容器中的服務,但這并不是一個好的方法,因為我們需要在每一個Servlet中都進行這樣的操作。

方法二:

我們可以寫一個類似于“org.springframework.web.struts.DelegatingRequestProcessor”的委托的Bean,然後通過配置的方法把我們的服務注入到servlet中,具體方法如下,

Step 1:編寫委托類DelegatingServletProxy

package com.telek.pba.base.util;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
 * 以下是類似org.springframework.web.struts.DelegatingRequestProcessor的一個委托
 * 用于通過配置的方法,在Servlet中注入Service
 * @author binghe
 * */
public class DelegatingServletProxy extends GenericServlet{
    private static final long serialVersionUID = 1L;
    private String targetBean;
    private Servlet proxy;
   @Override
   public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException{
           proxy.service(req, res);
   }
     /**
      * 初始化
      */
      public void init() throws ServletException {
          this.targetBean = getServletName();
          getServletBean();
          proxy.init(getServletConfig());
      }
     /**
      * 擷取Bean
      */
      private void getServletBean() {
          WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
          this.proxy = (Servlet) wac.getBean(targetBean);
      }
}      

Step 2:修改Web.xml配置

在純Servlet模式下,我們的配置方式如下(以下由于代碼高亮插件的問題,請将代碼中的#替換成尖括号)

<servlet>
  <description>活動發起子產品活動查詢分頁Servlet</description>
  <display-name>launchActivityQueryServlet</display>
  <servlet-name>LaunchActivityQueryServlet</servlet-name>
  <servlet-class>com.telek.pba.launch.servlet.LaunchActivityQueryServlet</servlet-class>
<servlet>
<servlet-mapping>
  <servlet-name>LaunchActivityQueryServlet</servlet-name>
  <url-pattern>/servlet/launch/LaunchActivityQueryServlet</url-pattern>
</servlet-mapping>
</servlet>      

如果采用我們這種代理的方法,則配置應該修改為:

<servlet>
  <description>活動發起子產品活動查詢分頁Servlet</description>
  <display-name>launchActivityQueryServlet</display>
  <servlet-name>launchActivityQueryServlet</servlet-name>
  <servlet-class>com.telek.pba.base.util.DelegatingServletProxy</servlet-class>
<servlet>
<servlet-mapping>
  <servlet-name>launchActivityQuery</servlet-name>
  <url-pattern>/servlet/launch/LaunchActivityQueryServlet</url-pattern>
</servlet-mapping>
</servlet>      

注意:預設情況下,Servlet的配置中,LaunchActivityQuery的首字母一般為大寫,而我們的标題中已注明,我們采用Spring的注解模式,如果是自動掃描注解的話,預設情況下,注解的value值為首字母小寫,即:launchActivityQuery,是以,在我們新的配置中,要注意将首字母改為小寫,否則會報無法找到Bean的錯誤。

Step 3:至此,我們就可以像SSH的注入方式一樣,注入Servlet了,以下是個小示例:

package com.telek.pba.launch.servlet;
import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import com.telek.pba.base.model.PbaUserInfo;
import com.telek.pba.launch.dao.IPbaActivityInfoCurrentDAO;
@Component
public class LaunchActivityQueryServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    //注入IPbaActivityInfoCurrentDAO
    @Resource
    private IPbaActivityInfoCurrentDAO pbaActivityInfoCurrentDAO;
    public LaunchActivityQueryServlet() {
        super();
    }
    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
        // Put your code here
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //sth to do
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //sth to do
    }
    public void init() throws ServletException {
        // Put your code here
    }
}      

最後,請留心在Spring配置檔案中,配置上自動掃描包的路徑:

<context:component-scan base-package="com.telek.pba.*.dao.impl,
                     com.telek.pba.*.service.impl,
                     com.telek.pba.*.servlet"/>      

大功告成!