在使用spring容器的web应用中,业务对象间的依赖关系都可以用context.xml文件来配置,并且由spring容器来负责依赖对象 的创建。如果要在servlet中使用spring容器管理业务对象,通常需要使用WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext())来获得WebApplicationContext,然后调用WebApplicationContext.getBean("beanName")来获得对象的引用,这实际上是使用了依赖查找来获得对象,并且在servlet代码中硬编码了应用对象的bean名字。为了能在servlet中感知spring中bean,可采用如下步骤来实现:

1- 将servlet作为bean定义在context.xml文件中,和要应用的bean定义放在一起;

2- 实现一个代理servlet,该servlet用WebApplicationContext来获得在context.xml中定义的servlet的对象,并将任务委托给context.xml中定义的servlet

3- 在web.xml中用ContextLoaderListener来初始化spring 的context,同时在代理servlet的定义中用初始化参数来定义context.xml中servlet的bean名字。

4- 在web.xml中定义代理servlet的mapping.

利用这种方式就将servlet和业务对象的依赖关系用spring 来进行管理,并且不用在servlet中硬编码要引用的对象名字。

例子代码如下:

(1)代理servlet:

=======================================================================

package chen;

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;

public class ServletToBeanProxy extends GenericServlet {
 
 private String targetBean;

 private Servlet proxy;
 
 
 public void init() throws ServletException {
  System.out.println("proxy init");
    this.targetBean = getInitParameter("targetBean");
    getServletBean();
    proxy.init(getServletConfig());
 }

 
 public void service(ServletRequest req, ServletResponse res)
   throws ServletException, IOException {
  
  proxy.service(req, res);

 }

 
 private void getServletBean() {
  
  WebApplicationContext wac =
   WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
  this.proxy = (Servlet)wac.getBean(targetBean);
  
 }
 
 
}

=================================================================================

 

(2)web.xml中配置

 <context-param>
  <param-name>contextConfigLoaction</param-name>
  <param-value>/WEB-INF/context.xml</param-value>
 </context-param>
 
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <servlet>
  <servlet-name>ProxyBean</servlet-name>
  <servlet-class>chen.ServletToBeanProxy</servlet-class>
  <init-param>
   <param-name>targetBean</param-name>
   <param-value>servletBean</param-value>
  </init-param>
 </servlet>

<servlet-mapping>
  <servlet-name>ProxyBean</servlet-name>
  <url-pattern>/ProxyBean</url-pattern>
 </servlet-mapping>

 

(3) 完成实际任务的servlet定义,该servlet会引用另一个Book的对象

======================= ServletBean.java=======================

package chen;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * Servlet implementation class for Servlet: ServletBean
 *
 */
 public class ServletBean extends javax.servlet.GenericServlet implements javax.servlet.Servlet {

  private Book book;
 
 
 
 public ServletBean() {
  super();
 }
 
 
 
 
 public void init() throws ServletException {
 
  super.init();
  
 }

 
 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  book.showInfo();
  
 }

 public Book getBook() {
  return book;
 }

 public void setBook(Book book) {
  this.book = book;
 }  
}

================================Book.java==============================

package chen;


public class Book {
 private String isbn;
 private String name;
 
 
 
 public String getIsbn() {
  return isbn;
 }
 public void setIsbn(String isbn) {
  this.isbn = isbn;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
 
 public void showInfo() {
  System.out.println("book info...");
 }
 
 
}

(4) context.xml配置

<beans>
 <bean id="book" class="chen.Book"/>
 <bean id="servletBean" class="chen.ServletBean">
  <property name="book">
   <ref bean="book"/>
  </property>
 </bean>
</beans>

 

注意,在web.xml中并不出现ServletBean的说明,取而代之的是ServletToBeanProxy的说明,并用初始化参数targetBean来定义要代理的Servlet在context.xml中的名字。

当在浏览器中输入http://localhost/webcontext/ProxyBean时 ,spring将会创建ServletBean一个实例,其引用的Book实例也会被创建。

对Filter,springframework1.2以后自带了org.springframework.web.filter.DelegatingFilterProxy 来实现Filter和业务对象之间的代理,不需要自行开发了。

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐