Spring MVC 如何在Spring应用程序中的Servlet过滤器中自动连接Bean?

o0lyfsai  于 2023-10-24  发布在  Spring
关注(0)|答案(2)|浏览(106)

spring-boot应用程序
我的项目中没有ApplicationContext.xmlweb.xml文件。我更喜欢避免它们,并使用Java代码配置所有内容。
我已经阅读了以下关于servlet过滤器中bean注入的文章。

  1. How can I get a Spring bean in a servlet filter?
  2. http://www.deadcoderising.com/2015-05-04-dependency-injection-into-filters-using-delegatingfilterproxy/
  3. spring injection in servlet filter
    阅读完它们后,我开始使用DelegatingFilterProxy
    我的问题是如何autowire到过滤器的bean,并避免使用xml文件,特别是对于DelegatingFilterProxy配置。
    代码片段可以从github.中的第二篇文章中获得。
public class AuditHandler {

    public void auditRequest(String appName, ServletRequest request) {
        System.out.println(appName + ": Received request from " + request.getRemoteAddr() );
    }
}

public class AuditFilter implements Filter {

    private final AuditHandler auditHandler;
    private String appName;

    public AuditFilter(AuditHandler auditHandler) {
        this.auditHandler = auditHandler;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        auditHandler.auditRequest(appName, request);
        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        appName = filterConfig.getInitParameter("appName");
    }

    public void destroy() {}
}

ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="auditHandler" class="com.deadcoderising.AuditHandler">
    </bean>

    <bean id="auditFilter" class="com.deadcoderising.AuditFilter">
        <constructor-arg ref="auditHandler"/>
    </bean>
</beans>

web.xml

<web-app version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         metadata-complete="true">

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext*.xml</param-value>
    </context-param>

    <filter>
        <filter-name>auditFilter</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>appName</param-name>
            <param-value>di-example</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>auditFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>
vom3gejh

vom3gejh1#

您应该将FilterRegistrationBean添加到您的主Application类(用@SpringBootApplication注解的类),并让Spring提供AuditHandler的示例:

@Bean
@Autowired
public FilterRegistrationBean auditFilterRegistration(AuditHandler handler) {
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    filterRegistrationBean.setFilter(new AuditFilter(handler));
    filterRegistrationBean.setOrder(3); // ordering in the filter chain
    return filterRegistrationBean;
}

如果这不起作用(例如,您的AuditHandler实现没有正确注解,或者它不在默认的包扫描路径上),您可以指示Spring提供它(也在您的@SpringBootApplication注解类中):

@Bean
public AuditHandler auditHandler() {
    return new AuditHandlerImplementation();
}
gab6jxml

gab6jxml2#

将以下代码添加到 *filter类 * 的 *init**方法中。

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

所以init方法看起来像这样:

public void init(FilterConfig filterConfig) throws ServletException {
        appName = filterConfig.getInitParameter("appName");
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
    }

现在,您可以使用@Autowired@Inject@Resource标记将依赖项(bean)注入到过滤器类中。

相关问题