有时在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. 我这样理解js里的this

    关于this,是很多前端面试必考的题目,有时候在网上看到这些题目,自己试了一下,额,还真的错了!在实际开发中,也会遇到 this 的问题(虽然一些类库会帮我们处理),例如在使用一些框架的时候,例如:k ...

  2. oracle 分组排序函数

    项目开发中,我们有时会碰到需要分组排序来解决问题的情况:1.要求取出按field1分组后,并在每组中按照field2排序:2.亦或更加要求取出1中已经分组排序好的前多少行的数据 这里通过一张表的示例和 ...

  3. 你应该知道的25道Javascript面试题

    题目来自 25 Essential JavaScript Interview Questions.闲来无事,正好切一下. 一 What is a potential pitfall with usin ...

  4. 关于开发中 hosts 文件的修改

    这篇文章只是给自己做个笔记吧. 最近的工作经常要改 hosts 文件(C:\Windows\System32\drivers\etc\hosts),并且改完后不立即生效.小胡子哥 提到: 因为服务器设 ...

  5. [MCSM]伪随机数和伪随机数生成器

    1. 几个问题 为什么需要随机数? 伪随机数伪在哪里? 为何要采用伪随机数代替随机数?这种代替是否有不利影响? 如何产生(伪)随机数? 以下内容将围绕这几个问题依次说明. 2. 参考 http://e ...

  6. [转]Win2003打不开https的问题

    转自:http://ljl-xyf.iteye.com/blog/2269834 碰到客户做问题是能打开https://www.baidu.com 这个网页 打不开 https://sha256.al ...

  7. Codeforces Round #359(div 2)

    A:= v = B:^ w ^ C:一天n个小时,一个小时m分(n,m十进制),一个手表有两部分,左边表示时,右边表示分,但都是7进制,而且手表上最多只能有7个数字且数字不能重复,现在要你算出能正确表 ...

  8. 3-cd 命令总结

  9. C++类功能扩展预留五招

    第一招虚函数 通过派生类来进行功能扩展是基本的面向对象的方式,这种方式大如下: class base { public: virtual ~base(){} virtual void fun() { ...

  10. C# 多线程join的用法,等待多个子线程结束后再执行主线程

    等待多个子线程结束后再执行主线程 class MultiThread{ #region join test public void MultiThreadTest() { Thread[] ths = ...