【问题标题】:how to autowire bean in the servlet filters in spring application?如何在 Spring 应用程序的 servlet 过滤器中自动装配 bean?
【发布时间】:2015-11-14 15:03:44
【问题描述】:

我有一个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>

【问题讨论】:

    标签: spring spring-mvc dependency-injection spring-boot autowired


    【解决方案1】:

    您应该将FilterRegistrationBean 添加到您的主应用程序类(使用@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();
    }
    

    【讨论】:

    • 如果我要应用多个过滤器,如何指定顺序?
    • FilterRegistrationBean#setOrder(int),我已经更新了答案。
    • 谢谢,我现在就测试一下
    • 我怎样才能在非弹簧启动应用程序中做同样的事情。 Spring MVC 中没有FilterRegistrationBean 可用
    • 过滤器也可以同样的方式注册到一个配置类中(类注解@Configuration
    猜你喜欢
    • 2015-12-10
    • 2011-12-14
    • 2019-04-06
    • 2014-11-26
    • 2022-08-20
    • 2014-04-22
    • 2011-01-28
    • 2012-08-11
    • 2013-11-11
    相关资源
    最近更新 更多