Spring 在 web.xml 中映射的 Filter 实现中注入
Spring injection in Filter implementation mapped in web.xml
web.xml:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.mypackage.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/myFilterPattern/*</url-pattern>
</filter-mapping>
我的过滤器:
public class MyFilter implements Filter {
@Autowired
InjectedBean someInjectedBean;
但是在拦截/myFilterPattern/*
请求时,MyFilter.doFilter(...)
中的someInjectedBean
仍然是null,也就是说没有被注入。相同的 bean (InjectedBean
) 在 web.xml.
中未引用的其他上下文组件中被很好地注入
是否因为容器过滤发生在Spring上下文之外?有什么方法可以在 web.xml 中映射 Filter 实现中的 Spring 注入?
由于 Filter 不是 spring bean(它是一个 web 组件),注入在它们内部不起作用。 Springs 不会在 Web 组件中注入。
使用 DelegatingFilterProxy,这是一个过滤器实现,它将 springbean 名称作为初始参数并将过滤器请求委托给该 bean。
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>myFilterBean</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/myFilterPattern/*</url-pattern>
</filter-mapping>
并在您的 spring 上下文中创建一个名为 myFilterBean 的 Bean。
public class MyFilter extends GenericFilterBean {
@Autowired
InjectedBean someInjectedBean;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
如果您使用 spring 安全并扩展 OncePerRequestFilter
,还有一个解决方案
@Component
public class CustomAuthorizationFilter extends OncePerRequestFilter{
@Autowired
ResourceConfig resourceConfig;
public CustomAuthorizationFilter() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
//...your code
仅从 doFilterInternal 块中的 resourceConfig 中提取详细信息很重要,这样您将获得值,否则您可能会出现空指针异常。
web.xml:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.mypackage.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/myFilterPattern/*</url-pattern>
</filter-mapping>
我的过滤器:
public class MyFilter implements Filter {
@Autowired
InjectedBean someInjectedBean;
但是在拦截/myFilterPattern/*
请求时,MyFilter.doFilter(...)
中的someInjectedBean
仍然是null,也就是说没有被注入。相同的 bean (InjectedBean
) 在 web.xml.
是否因为容器过滤发生在Spring上下文之外?有什么方法可以在 web.xml 中映射 Filter 实现中的 Spring 注入?
由于 Filter 不是 spring bean(它是一个 web 组件),注入在它们内部不起作用。 Springs 不会在 Web 组件中注入。
使用 DelegatingFilterProxy,这是一个过滤器实现,它将 springbean 名称作为初始参数并将过滤器请求委托给该 bean。
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>myFilterBean</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/myFilterPattern/*</url-pattern>
</filter-mapping>
并在您的 spring 上下文中创建一个名为 myFilterBean 的 Bean。
public class MyFilter extends GenericFilterBean {
@Autowired
InjectedBean someInjectedBean;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
如果您使用 spring 安全并扩展 OncePerRequestFilter
,还有一个解决方案@Component
public class CustomAuthorizationFilter extends OncePerRequestFilter{
@Autowired
ResourceConfig resourceConfig;
public CustomAuthorizationFilter() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
//...your code
仅从 doFilterInternal 块中的 resourceConfig 中提取详细信息很重要,这样您将获得值,否则您可能会出现空指针异常。