如何使用spring的autowire为servlet注入Bean

 我来答
huanglenzhi
2015-04-25 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517163
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
  在应用中一般普通的JavaPojo都是由Spring来管理的,所以使用autowire注解来进行注入不会产生问题,但是有两个东西是例外的,一个是 Filter,一个是Servlet,这两样东西都是由Servlet容器来维护管理的,所以如果想和其他的Bean一样使用Autowire来注入的 话,是需要做一些额外的功夫的。
对于Filter,Spring提供了DelegatingFilterProxy,所以本文主要讲述Servlet的解决。
1、比较直观但是不大优雅的做法是重写init()方法,在里面使用AutowireCapableBeanFactory来手工告诉Spring:我这个Servlet是需要这样的一个Bean的。具体写法:
  【1】不使用注解

  [java] view plaincopy
  // servlet中调用spring中的Bean
  application = getServletContext();
  wac = WebApplicationContextUtils.getWebApplicationContext(application);// 获取spring的context
  IClientDao clientDao = (IClientDao) wac.getBean("clientDaoBean");

  【2】获取注解

  [java] view plaincopy
  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就是需要注入的Bean在spring中注册的名字.
这样写的主要问题是就是那个BEAN_NAME,这样写有点主动查找,而不是依赖注入的感觉。

  2、创建一个类似于DelegatingFilterProxy那样的代理,通过代理根据配置来找到实际的Servlet,完成业务逻辑功能。
假定我们有一个Servlet名字叫UserServlet,需要注入一个UserManager,伪代码如下:

  [java] view plaincopy
  public class UserServlet extends HttpServlet {
  @Autowired(required = true)
  private UserManager userManager;
  }

第一步:

  [java] view plaincopy
  public class DelegatingServletProxy extends GenericServlet {
  private String targetBean;
  private Servlet proxy;
  
  @Override
  public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  proxy.service(req, res);
  }
  
  @Override
  public void init() throws ServletException {
  this.targetBean = getServletName();
  getServletBean();
  proxy.init(getServletConfig());
  }
  
  private void getServletBean() {
  WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
  this.proxy = (Servlet) wac.getBean(targetBean);
  }
  }

  [java] view plaincopy
  public class DelegatingServletProxy extends GenericServlet {
  private String targetBean;
  private Servlet proxy;
  
  @Override
  public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  proxy.service(req, res);
  }
  
  @Override
  public void init() throws ServletException {
  this.targetBean = getServletName();
  getServletBean();
  proxy.init(getServletConfig());
  }
  
  private void getServletBean() {
  WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
  this.proxy = (Servlet) wac.getBean(targetBean);
  }
  }

第二步:
配置web.xml文件,原来UserServlet的配置大致是这样的:

  [html] view plaincopy
  <servlet>
  <servlet-name>userServlet</servlet-name>
  <servlet-class>com.sample.UserServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  <servlet-name>userServlet</servlet-name>
  <url-pattern>/userServlet</url-pattern>
  </servlet-mapping>

  [html] view plaincopy
  <servlet>
  <servlet-name>userServlet</servlet-name>
  <servlet-class>com.sample.UserServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  <servlet-name>userServlet</servlet-name>
  <url-pattern>/userServlet</url-pattern>
  </servlet-mapping>

现在修改为

  [html] view plaincopy
  <servlet>
  
  <servlet-name>userServlet</servlet-name>
  <servlet-class>com.sample.DelegatingServletProxy</servlet-class>
  </servlet>
  
  <servlet-mapping>
  <servlet-name>userServlet</servlet-name>
  <url-pattern>/userServlet</url-pattern>
  </servlet-mapping>

或者另一种:

  [html] view plaincopy
  <servlet-name>menueInitServlet</servlet-name>
  <servlet-class>cc.jqkj.oa.servlet.DelegatingServletProxy</servlet-class>
  <init-param>
  <param-name>menue-init-file</param-name>
  <param-value>WEB-INF/menue.properties</param-value>
  </init-param>
  <load-on-startup>2</load-on-startup>
  </servlet>

注意,spring是根据Servlet的名字来查找被代理的Servlet的,所以,首先我们要在UserServlet类前面加上 @Component,来告诉Srping:我也是一个Bean。如果名称和Web.xml里面定义的不一样的话,可以在这里指定Bean的名字,比如: @Component(“userServlet”)
spring配置 文件中:

  [html] view plaincopy
  <bean id=”menueInitServlet”>
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式