写在前面

最近,一位读者出去面试前准备了很久,信心满满的去面试。没想到面试官的一个问题把他难住了。面试官的问题是这样的:如何使用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
}
}

最后,请留心在Spring配置文件中,配置上自动扫描包的路径:

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

大功告成!

好了,咱们今天就聊到这儿吧!别忘了给个在看和转发,让更多的人看到,一起学习一起进步!!

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

写在最后

如果觉得文章对你有点帮助,请微信搜索并关注「 冰河技术 」微信公众号,跟冰河学习Spring注解驱动开发。公众号回复“spring注解”关键字,领取Spring注解驱动开发核心知识图,让Spring注解驱动开发不再迷茫。

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

  1. 【Spring注解驱动开发】如何实现方法、构造器位置的自动装配?我这样回答让面试官很满意!

    在 冰河技术 微信公众号前面的文章中,我们介绍了如何使用注解来自动装配Spring组件.之前将的都是在来的字段上添加注解,那有没有什么方法可以实现方法.构造器位置的自动装配吗?今天我们就一起来探讨下如 ...

  2. 【Spring注解驱动开发】如何使用@Value注解为bean的属性赋值,我们一起吊打面试官!

    写在前面 在之前的文章中,我们探讨了如何向Spring的IOC容器中注册bean组件,讲解了有关bean组件的生命周期的知识.今天,我们就来一起聊聊@Value注解的用法. 项目工程源码已经提交到Gi ...

  3. 【Spring注解驱动开发】BeanPostProcessor在Spring底层是如何使用的?看完这篇我懂了!!

    写在前面 在<[String注解驱动开发]面试官再问你BeanPostProcessor的执行流程,就把这篇文章甩给他!>一文中,我们详细的介绍了BeanPostProcessor的执行流 ...

  4. 【Spring注解驱动开发】你还不会使用@Resource和@Inject注解?那你就out了!!

    写在前面 我在 冰河技术 微信公众号中发表的<[Spring注解驱动开发]使用@Autowired@Qualifier@Primary三大注解自动装配组件,你会了吗?>一文中,介绍了如何使 ...

  5. 【Spring注解驱动开发】二狗子让我给他讲讲@EnableAspectJAutoProxy注解

    写在前面 最近,二狗子入职了新公司,新入职的那几天确实有点飘.不过慢慢的,他发现他身边的人各个身怀绝技啊,有Spring源码的贡献者,有Dubbo源码的贡献者,有MyBatis源码的贡献者,还有研究A ...

  6. 【Spring注解驱动开发】聊聊Spring注解驱动开发那些事儿!

    写在前面 今天,面了一个工作5年的小伙伴,面试结果不理想啊!也不是我说,工作5年了,问多线程的知识:就只知道继承Thread类和实现Runnable接口!问Java集合,竟然说HashMap是线程安全 ...

  7. 1、课程简介-Spring 注解驱动开发

    1.课程简介-Spring 注解驱动开发

  8. 0、Spring 注解驱动开发

    0.Spring注解驱动开发 0.1 简介 <Spring注解驱动开发>是一套帮助我们深入了解Spring原理机制的教程: 现今SpringBoot.SpringCloud技术非常火热,作 ...

  9. 【Spring注解驱动开发】组件注册-@ComponentScan-自动扫描组件&指定扫描规则

    写在前面 在实际项目中,我们更多的是使用Spring的包扫描功能对项目中的包进行扫描,凡是在指定的包或子包中的类上标注了@Repository.@Service.@Controller.@Compon ...

随机推荐

  1. web自动化之执行js脚本

    from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from seleni ...

  2. unicode 的中文字符串,调用 isalnum()返回的是 True ?

    描述 Python isalnum() 方法检测字符串是否由字母和数字组成. 语法 isalnum()方法语法: str.isalnum() 返回值 如果 string 至少有一个字符并且所有字符都是 ...

  3. css变量的使用

    css变量的使用 1.介绍:我们也可以在css中定义变量,和less.sass一样,通过--来定义变量 div { /* 开始定义变量 */ --color: red; /* 通过var()函数来使用 ...

  4. 《HelloGitHub》第 50 期

    兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...

  5. 基于 kubeadm 搭建高可用的kubernetes 1.18.2 (k8s)集群 三 集群可用性测试

    1. 创建nginx ds # 写入配置 $ cat > nginx-ds.yml <<EOF apiVersion: v1 kind: Service metadata: name ...

  6. Car的旅行路线 luogu P1027 (Floyd玄学Bug有点毒瘤)

    luogu题目传送门! Car的旅行路线  问题描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一 ...

  7. Python 每日一练(2)

    引言 我又双叒叕的来啦,新博客的第二篇文章,这次是继之前公众号上每日一练的第二个,这次是专题实对于文件的一些处理的练习 主要有以下几类: 1.实现英文文章字频统计 2.统一剪裁某一指定目录下的所有图片 ...

  8. Web缓存欺骗

    该漏洞主要是cdn安全配置的问题,cdn主要存储以下文件,加快访问速度 class, css, jar, js, jpg, jpeg, gif, ico, png, bmp, pict, csv, d ...

  9. vue 使用 elementUI 和 antd 的细微差别

    Checkbox a-checkbox 没有value属性,绑定用checked Collapse 使用折叠面板的时候,antd 的层级关系是 .ant-collapse >.ant-colla ...

  10. css定位和css3的基本

    定位方式:position需要搭配left|right |top |bottom 1.相对定位:相对于自身的位置进行偏移position: relative; 2.绝对定位:相对于有position属 ...