有时在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. Oracle:ODP.NET Managed 小试牛刀

    “ODP.NET Managed”发布已经有一段时间了,近期正好有一个新项目,想尝试用一下,参考园子里的文章:<.NET Oracle Developer的福音——ODP.NET Managed ...

  2. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  3. 一个用react+nodejs实现的笔记本小应用

    寒假回家产品经理一直叮嘱着要继续做学校团队的辣个项目,但是...,我到现在一点都还没做,而且还销声匿迹躲了起来藏了几天,是的我干了票大的,想把项目用一种新的架构实现了,所以这几天一直在偷偷摸摸的做一些 ...

  4. dnsunlocker解决

    环境:windows 10 中文企业版,firefox47, chrome51 安装了某个国外程序后,浏览器各种不正常,打开网页慢,或是无法打开,更严重的是会弹广告,各种广告. 然后在控制面板中卸载了 ...

  5. tr命令

    tr命令是linux下一个字符处理命令,用途:    字符替换    字符删除    字符压缩形式:tr [OPTION]... SET1 [SET2]接口:输入输出都是标准流,所以要通过管道来调用这 ...

  6. 48-tree 命令总结

  7. PHP中错误处理集合

    PHP错误处理 错误的分类 通常分3种: 语法错误: 程序运行之前,都要先检查语法.如果语法有错误,就会立即报错,并且不会去执行程序. 运行时错误: 就是在程序语法检查通过后,,开始运行程序并在此过程 ...

  8. ceph calamari 监控系统安装 on ubuntu 14.04

    在 ubuntu 14.04 上安装ceph calamari时,遇到calamari web界面中node server可以正常添加,但cluster 集群无法显示的问题. 经过定位,是因为salt ...

  9. Web Api单元测试写法

    例如我们在Web Api项目中有个Controller public class SomeController : ApiController { public HttpResponseMessage ...

  10. 关于ExtJS、JQuery UI和easy UI的选择问题

    转自百度知道. 问:做企业级应用,比如***管理系统,不需要华丽的特效,只希望简单,风格统一.能用到的只有messagebox.tree.grid大概这几个,其他特效不要,忘大神根据自己的见解以及我这 ...