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 中提取详细信息很重要,这样您将获得值,否则您可能会出现空指针异常。