在很多时候都有这个需求, 就是在某个过滤或拦截 中去调用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 是一致的;