【Spring注解驱动开发】面试官:如何将Service注入到Servlet中?朋友又栽了!!

最近,一位读者出去面试前准备了很久,信心满满的去面试。没想到面试官的一个问题把他难住了。面试官的问题是这样的:如何使用Spring将Service注入到Servlet中呢?这位读者平时也是很努力的,看什么源码啊、多线程啊、高并发啊、设计模式啊等等。没想到却在一个很简单的问题上栽了跟头,这就说明学习知识要系统化,要有条理,切忌东学一点,西记一点,否则,到头来,啥也学不到。

项目工程源码已经提交到GitHub:https://github.com/sunshinelyz/spring-annotation

如何实现将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 } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwyyyx.html