在很多時候都有這個需求, 就是在某個過濾或攔截 中去調用service層得某個方法來判斷,可苦惱於
filter或interceptor 是web容器管理,如何去取spring容器管理下的對象呢? 下面爲你解析:
1、webApplicationContext
webApplicationContext是spring在web容器初始化後初始化的web應用上下文環境,從中可以去到spring
管理下的對象;從WebApplicationContext 源碼分析, 它持有ServletContext並繼承自ApplicationContext,
也就是可以使用spring容器和web容器的context。
下面是WebApplicationContextUtil的得到WebApplicationContext的源碼,可知
public static WebApplicationContext getRequiredWebApplicationContext(ServletContext sc)
throws IllegalStateException {
WebApplicationContext wac = getWebApplicationContext(sc);
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
}
return wac;
}
而WebApplicationContext則需要從ServletContext取出,Spring提供了一個WebApplicationContextUtils類,
可以方便的取出WebApplicationContext,只要把ServletContext傳入即可。
2、filter的代理類.
public class ServletProxy extends HttpServlet {
private String targetBean;
private Servlet proxy;
public void init() throws ServletException {
targetBean = getInitParameter("targetBean");
proxy = ServletProxyUtil
.getServletBean(targetBean, getServletContext());
proxy.init(getServletConfig());
}
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
proxy.service(request, response);
}
}
工具類得到 filter或 interceptor:
public class ServletProxyUtil {
/**
* 得到Servlet
* @param targetBean
* @param servletContext
* @return
*/
public static Servlet getServletBean(String targetBean,
ServletContext servletContext) {
WebApplicationContext context = WebApplicationContextUtils
.getRequiredWebApplicationContext(servletContext);
return (Servlet) context.getBean(targetBean);
}
/**
* 得到filter
* @param targetBean
* @param servletContext
* @return
*/
public static Filter getFilterBean(String targetBean,ServletContext servletContext){
WebApplicationContext context = WebApplicationContextUtils
.getRequiredWebApplicationContext(servletContext);
return (Filter) context.getBean(targetBean);
}
}
xml 文件配置代理:
<!-- filter 中得到 spring注入的service -->
<filter>
<filter-name>filterProxy</filter-name>
<filter-class>com.sslinm.web.servlet.FilterProxy</filter-class>
<init-param>
<param-name>targetBean</param-name>
<!-- 要得到的真正filter 在spring配置中的bean id -->
<param-value>myFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filterProxy</filter-name>
<url-pattern>/user/*</url-pattern>
</filter-mapping>
3、寫一個filter 類完成你的業務邏輯並將使用的filter讓spring 容器替你管理起來, 確保這裏bean 的id 和xml中param-value 是一致的;