一文詳解Springboot中filter的原理與注冊(cè)
1、filter
先看下web服務(wù)器的filter所處的位置。filter是一個(gè)前后連接的鏈,前面處理完成之后傳遞給下一個(gè)filter處理。

1.1 filter的接口定義
public interface Filter {
//初始化方法,整個(gè)生命周期中只執(zhí)行一次。
//在init方法成功(失敗如拋異常等)執(zhí)行完前,不能提供過濾服務(wù)。
//參數(shù)FilterConfig用于獲取初始化參數(shù)
public void init(FilterConfig filterConfig) throws ServletException;
//執(zhí)行過濾任務(wù)的方法,參數(shù)FilterChain表示過濾器鏈,doFilter方法中只有執(zhí)行chain.doFilter()后才能調(diào)用下一個(gè)過濾器的doFilter方法
//才能將請(qǐng)求交經(jīng)下一個(gè)Filter或Servlet執(zhí)行
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
//銷毀方法,當(dāng)移出服務(wù)時(shí)由web容器調(diào)用。整個(gè)生命周期中destroy方法只會(huì)執(zhí)行一次
//destroy方法可用于釋放持有的資源,如內(nèi)存、文件句柄等
public void destroy();
}
filter的入?yún)⑹莚equest和response,filter一般是用來做一些預(yù)處理工作,比如做一些檢查,驗(yàn)證等工作。
1.2 自定義filter
public class LoginFilter implements Filter {
@Override
public void destroy() {
System.out.println("filter destroy method");
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("filter doFilter method ");
// 繼續(xù)傳遞下去
filterChain.doFilter(arg0,arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("filter init method");
}
}2、springboot中filter注冊(cè)幾種方式
2.1 手動(dòng)注冊(cè)
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean indexFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean(new LoginFilter());
registration.addUrlPatterns("/");
return registration;
}
}
2.2 注解注冊(cè)
2.2.1 在filter上增加注解@WebFilter
@WebFilter(urlPatterns = "/",filterName = "filter1")
@Order(1)
public class LoginFilter implements Filter {
@Override
public void destroy() {
System.out.println("filter destroy method");
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("filter doFilter method 1 ");
filterChain.doFilter(arg0,arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("filter init method");
}
}2.2.2 在啟動(dòng)類上增加注解@ServletComponentScan
@SpringBootApplication
@ServletComponentScan
public class FilterTestApplication {
public static void main(String[] args) {
SpringApplication.run(FilterTestApplication.class, args);
}
}
注:
@ServletComponentScan 會(huì)掃描所有的帶有@WebFilter的類,并且注冊(cè)為servlet。
如果啟動(dòng)類不添加此注解,在filter上添加Component注解也可以注冊(cè)為filter
order注解可以調(diào)整filter的順序
2.3 通過servletContext 注冊(cè)
@Autowired ServletContext servletContext; servletContext.addFilter()
3、原理
3.1 ServletContext
Web容器在啟動(dòng)時(shí)會(huì)為每個(gè)web應(yīng)用創(chuàng)建一個(gè)ServletContext對(duì)象,而這個(gè)ServletContext對(duì)象就代表當(dāng)前這個(gè)web應(yīng)用。
一個(gè)ServletContext對(duì)象代表一個(gè)web應(yīng)用,web應(yīng)用中所有的Servlet和其他資源都共享一個(gè)ServletContext對(duì)象,
如果有必要我們就可以通過ServletContext對(duì)象進(jìn)行Servlet之間的通訊。
ServletContext,是一個(gè)全局的儲(chǔ)存信息的空間,服務(wù)器開始,其就存在,服務(wù)器關(guān)閉,其才釋放。request,一個(gè)用戶可有多個(gè);session,一個(gè)用戶一個(gè);而servletContext,所有用戶共用一個(gè)。

ApplicationContext 是ServletContext的實(shí)現(xiàn)類,可以看到里面有相應(yīng)的注冊(cè)的方法
在程序中獲取ServletContext
3.1.1 使用自動(dòng)注入
@Autowired private ServletContext servletContext;
3.1.2 request獲取servletContext
ServletContext servletContext = request.getServletContext();
3.1.3 實(shí)現(xiàn) ServletContextListener
@Component
public class TestListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println(sce);
}
}
3.2 ServletRegistrationBean
看下Filter的定義,可以看到和webfilter注解內(nèi)容一樣
public class ServletRegistrationBean<T extends Servlet> extends DynamicRegistrationBean<ServletRegistration.Dynamic> {
private static final String[] DEFAULT_MAPPINGS = new String[]{"/*"};
private T servlet;
private Set<String> urlMappings;
private boolean alwaysMapUrl;
private int loadOnStartup;
private MultipartConfigElement multipartConfig;
......
}
在開發(fā)中一般使用他的子類FilterRegistrationBean,使用上面2.1 手動(dòng)注冊(cè)
4、總結(jié)
filter 作為web服務(wù)器中的重要的一部分,一般常用來做一些前置處理和對(duì)調(diào)用請(qǐng)求的中斷
filter的注冊(cè)幾種方式總結(jié),在開發(fā)中一般靈活使用,沒有特殊的請(qǐng)求,常規(guī)都?jí)蛴?/p>
了解原理是為了更好的理解,filter的過濾鏈?zhǔn)絊pring Security的重要切入點(diǎn),理解了filter再理解其他的框架就不難了,甚至可以自己簡(jiǎn)單寫出一個(gè)列斯的框架
到此這篇關(guān)于一文詳解Springboot中filter的原理與注冊(cè)的文章就介紹到這了,更多相關(guān)Springboot filter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Java企業(yè)級(jí)項(xiàng)目開發(fā)思想
Java企業(yè)級(jí)項(xiàng)目開發(fā)思想。偶遇,讀有所得,遂分享給大家,本文不涉及案例,只談思想和理念,需要的朋友可以參考。2017-09-09
SpringBoot中YAML語(yǔ)法及幾個(gè)注意點(diǎn)說明
這篇文章主要介紹了SpringBoot中YAML語(yǔ)法及幾個(gè)注意點(diǎn)說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02

