在使用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和業務對象之間的代理,不需要自行開發了。