有时在Spring(3.2.5)项目中,如果使用到Servlet,可能希望Servlet实例作为bean受Spring容器管理,这样也能自动注入其他需要的bean,查了下,发现只针对过滤器提供了代理类org.springframework.web.filter.DelegatingFilterProxy,并没有提供针对Servlet的代理类,于是模仿着写了下面的代理类:
  
package org.springframework.web.servlet;
 
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
 
 
/**
 *  Servlet代理类,将Servlet托管于Spring容器,以便直接在Servlet内部自动注入其他bean<br>
 *  参考 {@code org.springframework.web.filter.DelegatingFilterProxy}<br>
 */
@SuppressWarnings("serial")
public class DelegatingServletProxy extends HttpServletBean {
 
 private String contextAttribute;
 private WebApplicationContext webApplicationContext;
 private String targetBeanName;
 private boolean targetServletLifecycle = true;
 private volatile Servlet delegate;
 private final Object delegateMonitor = new Object();
 
 public DelegatingServletProxy() {
 }
 
 public DelegatingServletProxy(Servlet delegate) {
  Assert.notNull(delegate, "delegate Servlet object must not be null");
  this.delegate = delegate;
 }
 
 public DelegatingServletProxy(String targetBeanName) {
  this(targetBeanName, null);
 }
 
 public DelegatingServletProxy(String targetBeanName, WebApplicationContext wac) {
  Assert.hasText(targetBeanName, "target Servlet bean name must not be null or empty");
  this.setTargetBeanName(targetBeanName);
  this.webApplicationContext = wac;
  if (wac != null) {
   this.setEnvironment(wac.getEnvironment());
  }
 }
 
 public void setContextAttribute(String contextAttribute) {
  this.contextAttribute = contextAttribute;
 }
 
 public String getContextAttribute() {
  return this.contextAttribute;
 }
 
 public void setTargetBeanName(String targetBeanName) {
  this.targetBeanName = targetBeanName;
 }
 
 protected String getTargetBeanName() {
  return this.targetBeanName;
 }
 
 public void setTargetServletLifecycle(boolean targetServletLifecycle) {
  this.targetServletLifecycle = targetServletLifecycle;
 }
 
 protected boolean isTargetServletLifecycle() {
  return this.targetServletLifecycle;
 }
 
 @Override
 protected void initServletBean() throws ServletException {
  synchronized (this.delegateMonitor) {
   if (this.delegate == null) {
    if (this.targetBeanName == null) {
     this.targetBeanName = this.getServletName();
    }
    WebApplicationContext wac = this.findWebApplicationContext();
    if (wac != null) {
     this.delegate = this.initDelegate(wac);
    }
   }
  }
 }
 
 @Override
 public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
  Servlet delegateToUse = this.delegate;
  if (delegateToUse == null) {
   synchronized (this.delegateMonitor) {
    if (this.delegate == null) {
     WebApplicationContext wac = this.findWebApplicationContext();
     if (wac == null) {
      throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
     }
     this.delegate = this.initDelegate(wac);
    }
    delegateToUse = this.delegate;
   }
  }
  this.invokeDelegate(delegateToUse, req, resp);
 }
 
 @Override
 public void destroy() {
  Servlet delegateToUse = this.delegate;
  if (delegateToUse != null) {
   this.destroyDelegate(delegateToUse);
  }
 }
 
 protected WebApplicationContext findWebApplicationContext() {
  if (this.webApplicationContext != null) {
   if (this.webApplicationContext instanceof ConfigurableApplicationContext) {
    if (!((ConfigurableApplicationContext) this.webApplicationContext).isActive()) {
     ((ConfigurableApplicationContext) this.webApplicationContext).refresh();
    }
   }
   return this.webApplicationContext;
  }
  String attrName = this.getContextAttribute();
  if (attrName != null) {
   return WebApplicationContextUtils.getWebApplicationContext(super.getServletContext(), attrName);
  }
  else {
   return WebApplicationContextUtils.getWebApplicationContext(super.getServletContext());
  }
 }
 
 protected Servlet initDelegate(WebApplicationContext wac) throws ServletException {
  Servlet delegate = wac.getBean(this.getTargetBeanName(), Servlet.class);
  if (this.isTargetServletLifecycle()) {
   delegate.init(super.getServletConfig());
  }
  return delegate;
 }
 
 protected void invokeDelegate(Servlet delegate, ServletRequest req, ServletResponse resp) throws ServletException, IOException {
  delegate.service(req, resp);
 }
 
 protected void destroyDelegate(Servlet delegate) {
  if (this.isTargetServletLifecycle()) {
   delegate.destroy();
  }
 }
 
}
 
//======================================================//
用法:
1、比如存在test.TestServlet,配置到spring对应xml中:
 <bean id="testServlet" class="test.TestServlet" />
 
2、在web.xml配置如下:
<servlet>
  <servlet-name>testServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DelegatingServletProxy</servlet-class>
  <init-param>
   <param-name>targetBeanName</param-name>
   <param-value>testServlet</param-value>
  </init-param>
  <load-on-startup>10</load-on-startup>
 </servlet>
 
然后在TestServlet中可自动注入需要的bean。

整合Servlet到Spring容器的更多相关文章

  1. spring boot整合servlet、filter、Listener等组件方式

    创建一个maven项目,然后此项目继承一个父项目:org.springframework.boot 1.创建一个maven项目: 2.点击next后配置父项目及版本号 3.点击finish后就可查看p ...

  2. spring boot 2.x 系列 —— spring boot 整合 servlet 3.0

    文章目录 一.说明 1.1 项目结构说明 1.2 项目依赖 二.采用spring 注册方式整合 servlet 2.1 新建过滤器.监听器和servlet 2.2 注册过滤器.监听器和servlet ...

  3. spring 整合 servlet

    目的:记录spring整合 servlet过程demo.(企业实际开发中可能很少用到),融会贯通. 前言:在学习spring 过程(核心 ioc,aop,插一句 学了spring 才对这个有深刻概念, ...

  4. Servlet自动注入Spring容器中的Bean解决方法

    很多情况在进行Web开发的时候需要自己手写Servlet来完成某些功能,而servlet有需要注入Spring容器中的某些bean,这是每次都要手动获取比较麻烦,这里有一个解决方案,只需要写一个ser ...

  5. 如何在servlet的监听器中使用spring容器的bean

    另外补充下:在web Server容器中,无论是Servlet,Filter,还是Listener都不是Spring容器管理的,因此我们都无法在这些类中直接使用Spring注解的方式来注入我们需要的对 ...

  6. Spring管理Filter和Servlet(在servlet中注入spring容器中的bean)

    在使用spring容器的web应用中,业务对象间的依赖关系都可以用context.xml文件来配置,并且由spring容器来负责依赖对象 的创建.如果要在servlet中使用spring容器管理业务对 ...

  7. servlet容器,web容器,spring容器,springmvc容器的区别(转)

    web容器中有servlet容器,spring项目部署后存在spring容器和springmvc容器.其中spring控制service层和dao层的bean对象.springmvc容器控制contr ...

  8. Web容器、Servlet容器、Spring容器、SpringMVC容器之间的关系

    以下内容为个人理解,如有误还请留言指出,不胜感激! Web容器 web容器(web服务器)主要有:Apache.IIS.Tomcat.Jetty.JBoss.webLogic等,而Tomcat.Jet ...

  9. Spring Boot整合Servlet,Filter,Listener,访问静态资源

    目录 Spring Boot整合Servlet(两种方式) 第一种方式(通过注解扫描方式完成Servlet组件的注册): 第二种方式(通过方法完成Servlet组件的注册) Springboot整合F ...

随机推荐

  1. 一道javascript面试题

    下面表达式比较的结果分别是什么? 1. []=="0" 2. []==0 3. "0"==0 4. []==false 5. []==[] 大家可以试试写下自己 ...

  2. CSS基本知识0-命名规范

    CSS命名及规范是第一步: 总起:所有名字小写,样式名用-号连接,如.nav-left,CSS使用小写加连接,那么ID就使用大写不加连接,比如UserName,把它和编程的属性对应起来,那么方法就以小 ...

  3. 51单片机中断interrupt……using……

    51单片机中断细节的一些问题. interrupt0:外部中断0interrupt1:定时器中断0interrupt2:外部中断interrupt3:定时器中断1interrupt4:串口 using ...

  4. 自然数从1到n之间,有多少个数字含有1

        问题明确而简单.for循环肯定是不好的.       用递推方法:       定义h(n)=从1到9999.....9999  ( n 个 9)之间含有1的数字的个数.定义f(n)为n位数中 ...

  5. python内置数据类型-字典和列表的排序 python BIT sort——dict and list

    python中字典按键或键值排序(我转!)   一.字典排序 在程序中使用字典进行数据信息统计时,由于字典是无序的所以打印字典时内容也是无序的.因此,为了使统计得到的结果更方便查看需要进行排序. Py ...

  6. 【Python】 [基础] 条件判断 与 循环 与dict和set

    # 条件判断 elif:  else if 的作用 注意: : [冒号]BMI =w/(h*h) if BMI<15:    print('较轻')elif BMI<25:    prin ...

  7. Yii 字段验证

    关于验证的属性: $enableClientValidation:是否在客户端验证,也即是否生成前端js验证脚本(如果在form中设置了ajax验证,也会生成这个js脚本). $enableAjaxV ...

  8. js中用正则表达式 过滤特殊字符 ,校验所有输入域是否含有特殊符号

    function stripscript(s) { var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~ ...

  9. HoG

    实现步骤 先计算每一个像素点位置上x和y方向上的梯度. 这样在每一个像素点位置上得到一个二维向量, 计算它的方向和模长 将图片分为一个个的cell, 如\(8\times 8\). 计算它的HOG: ...

  10. EPUBBuilder编辑器新版

    epub全称为Electronic Publication的缩写,意为:电子出版, epub于2007年9月成为国际数位出版论坛(IDPF)的正式标准,以取代旧的开放Open eBook电子书标准,e ...