springboot自定義filter學習筆記

        自定義Filter,首先要本身寫一個類,實現java.sevlet.Filter接口的init、doFilter和destroy三個方法。java

        在web項目中,經過web.xml中的<filter>標籤,能夠將該自定義filter交由容器實例化,而後經過<filter-mapping>標籤配置過濾路徑。若是須要將該filter使用spring管理,好比該filter須要用到spring的其餘bean,那麼能夠在web.xml中配置spring的filter代理類org.springframework.web.filter.DelegatingFilterProxy實現,在spring中實例化須要代理的filer爲bean,只要保證<filter-name>和bean的id一致便可。注意須要設置代理filter的targetFilterLifecycle爲true: web

<filter>
    <filter-name>myfilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
      <!-- 這個配置我沒聽懂說的什麼意思,大概是說保證bean的生命週期要和filter保持一致 -->
      <param-name>targetFilterLifecycle</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>myfilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

 

        在springboot中項目中有三種方式讓該自定義filter生效。spring

1.方法一: springboot提供了註冊filer的類FilterRegistrationBean,實例化該類可註冊自定義filter,代碼以下:springboot

@Configuration
public class ApplicationConfiguration{
    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        MyFilter myFilter = new MyFilter();
        filterRegistrationBean.setFilter(myFilter);
        List<String> urls = new ArrayList<>();
        urls.add("/users/*");
        filterRegistrationBean.setUrlPatterns(urls);//配置過濾規則
        return filterRegistrationBean;
    }
}

Springboot還提供了註解實現的方式,這裏再也不贅述,主要是自定義filter類上增長@WebFilter的註解來實現。app

2.方法二,藉助spring的filter代理類DelegatingFilterProxy和springboot的FilterRegistrationBean一塊兒實現,代碼以下:url

@Configuration
public class ApplicationConfiguration{
    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new DelegatingFilterProxy("myFilter"));
        filterRegistration.addInitParameter("targetFilterLifecycle", "true");
		filterRegistration.setEnabled(true);
		filterRegistration.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
}

springboot中還有一種合併起來的寫法,代碼以下:代理

@Configuration
public class ApplicationConfiguration{
	@Bean
    public DelegatingFilterProxyRegistrationBean delegatingFilterProxyRegistrationBean(){
        DelegatingFilterProxyRegistrationBean bean = new DelegatingFilterProxyRegistrationBean("myFilter");
        bean.addInitParameter("targetFilterLifecycle", "true");
        bean.setEnabled(true);
        bean.addUrlPatterns("/*");
        return bean;
    }
}

3.方法三,直接實例化自定義的Filter,可是這種Filter沒法定義攔截規則,默認全局攔截,慎用。code

 

        第一種和第二種方法本質是同樣的,,主要就是FilterRegistrationBean這個類,經過AbstractFilterRegistrationBean接口間接實現了ServletContextInitializer,在springboot中啓動容器後會查找實現該接口的bean,並調用onStartup()方法將自定義的Filter添加到容器中。xml

        二者的區別是方法一直接設置Filter,該Filter能夠不用spring管理,好比上面方法一的代碼所示,直接new MyFilter(),也能夠由spring管理,好比將new MyFilter()的地方換成方法三的方式實現(此時方法三形式的filter將不會做爲全局過濾器了)。而方法二經過DelegatingFilterProxy傳入filter名字,在WebApplicationContext查找該Filter Bean,並將DelegatingFilterProxy生成的Bean做爲filter的代理對象,這樣作的目的是,和有web.xml時的項目同樣,容器加載時先加載代理Filter,不須要直接加載真正的Filter,達到懶加載的效果(有web.xml時的項目使用代理filter,必須懶加載,由於在web.xml加載filter的時候,spring中真正的filter bean尚未建立。)。對象

相關文章
相關標籤/搜索