【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
}
}
最后,请留心在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中?朋友又栽了!!的更多相关文章
- 【Spring注解驱动开发】如何实现方法、构造器位置的自动装配?我这样回答让面试官很满意!
在 冰河技术 微信公众号前面的文章中,我们介绍了如何使用注解来自动装配Spring组件.之前将的都是在来的字段上添加注解,那有没有什么方法可以实现方法.构造器位置的自动装配吗?今天我们就一起来探讨下如 ...
- 【Spring注解驱动开发】如何使用@Value注解为bean的属性赋值,我们一起吊打面试官!
写在前面 在之前的文章中,我们探讨了如何向Spring的IOC容器中注册bean组件,讲解了有关bean组件的生命周期的知识.今天,我们就来一起聊聊@Value注解的用法. 项目工程源码已经提交到Gi ...
- 【Spring注解驱动开发】BeanPostProcessor在Spring底层是如何使用的?看完这篇我懂了!!
写在前面 在<[String注解驱动开发]面试官再问你BeanPostProcessor的执行流程,就把这篇文章甩给他!>一文中,我们详细的介绍了BeanPostProcessor的执行流 ...
- 【Spring注解驱动开发】你还不会使用@Resource和@Inject注解?那你就out了!!
写在前面 我在 冰河技术 微信公众号中发表的<[Spring注解驱动开发]使用@Autowired@Qualifier@Primary三大注解自动装配组件,你会了吗?>一文中,介绍了如何使 ...
- 【Spring注解驱动开发】二狗子让我给他讲讲@EnableAspectJAutoProxy注解
写在前面 最近,二狗子入职了新公司,新入职的那几天确实有点飘.不过慢慢的,他发现他身边的人各个身怀绝技啊,有Spring源码的贡献者,有Dubbo源码的贡献者,有MyBatis源码的贡献者,还有研究A ...
- 【Spring注解驱动开发】聊聊Spring注解驱动开发那些事儿!
写在前面 今天,面了一个工作5年的小伙伴,面试结果不理想啊!也不是我说,工作5年了,问多线程的知识:就只知道继承Thread类和实现Runnable接口!问Java集合,竟然说HashMap是线程安全 ...
- 1、课程简介-Spring 注解驱动开发
1.课程简介-Spring 注解驱动开发
- 0、Spring 注解驱动开发
0.Spring注解驱动开发 0.1 简介 <Spring注解驱动开发>是一套帮助我们深入了解Spring原理机制的教程: 现今SpringBoot.SpringCloud技术非常火热,作 ...
- 【Spring注解驱动开发】组件注册-@ComponentScan-自动扫描组件&指定扫描规则
写在前面 在实际项目中,我们更多的是使用Spring的包扫描功能对项目中的包进行扫描,凡是在指定的包或子包中的类上标注了@Repository.@Service.@Controller.@Compon ...
随机推荐
- Codeblocks运行按钮变灰,卡程序编译
实际上,当我们点击绿色运行按钮运行之后,.exe文件会开始运行,当我们点击红色调试按钮之后,会开始调试. 因此当我们在运行卡住之后,点击红色调试按钮,实际上并没有真正的结束程序,只是将窗口隐藏起来,我 ...
- Meta标签基本使用
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><t ...
- Istio Sidecar
概念及示例 Sidecar描述了sidecar代理的配置.默认情况下,Istio 让每个 Envoy 代理都可以访问来自和它关联的工作负载的所有端口的请求,然后转发到对应的工作负载.您可以使用 sid ...
- Kubernetes Ingress简单入门
作者:Nick Ramirez 原文链接:https://thenewstack.io/kubernetes-ingress-for-beginners/ 本文转载自Rancher Labs 不知道你 ...
- Linux学习(一):常用命令
init 0:关机 init 3:命令行模式 init 5:图形界面模式 init 6:重启 shutdown -h now:立马关机 ls:文件列表 参数:-l 详细列表 cd:切换目录 用法实例: ...
- leetcode350之实现求解两数组交集(包含重复元素)
给定两个数组,编写一个函数来计算它们的交集. 说明: 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致. 我们可以不考虑输出结果的顺序 def binarySearch(nums, t ...
- Java IO(九)FilterInputStream 和 FilterOutputStream
Java IO(九)FilterInputStream 和 FilterOutputStream 一.介绍 FilterInputStream 和 FilterOutputStream 是过滤字节输入 ...
- nmap script 总结
一些常用脚本用法 nmap 脚本一些支持笼统扫描 usag. nmap -F --script auth 10.0.0.1 auth: 负责处理鉴权证书(绕开鉴权)的脚本 broadcast: 在局域 ...
- keras常见问题
问题:AttributeError: 'CRF' object has no attribute '_outbound_nodes' 解答:这个一般情况下是keras版本的问题,将其改为keras== ...
- 网络编程TCP/IP详解
网络编程TCP/IP详解 1. 网络通信 中继器:信号放大器 集线器(hub):是中继器的一种形式,区别在于集线器能够提供多端口服务,多口中继器,每个数据包的发送都是以广播的形式进行的,容易阻塞网络. ...