Spring Web學習--DelegatingFilterProxy 代理Filter
阿新 • • 發佈:2019-01-26
Spring web在設計的時候考慮到某些功能的實現是通過Filter來攔截進行實現的,如果直接的簡單的實現幾個Filter好像也不是不可以(平時我們就是這麼用的),但是Spring框架最核心的是IOC容器,和Spring框架最好的實現就是將要實現的Filter功能註冊到IOC容器的一個Bean,這樣就可以和Spring IOC容器進行完美的融合,所以Spring Web設計了DelegatingFilterProxy。本質上來說DelegatingFilterProxy就是一個Filter,其間接實現了Filter介面,但是在doFilter中其實呼叫的從Spring 容器中獲取到的代理Filter的實現類delegate。
1、DelegatingFilterProxy根據targetBeanName從Spring 容器中獲取被注入到Spring 容器的Filter實現類,在DelegatingFilterProxy配置時一般需要配置屬性targetBeanName
@Override protected void initFilterBean() throws ServletException { synchronized (this.delegateMonitor) { if (this.delegate == null) { // If no target bean name specified, use filter name. //當Filter配置時如果沒有設定targentBeanName屬性,則直接根據Filter名稱來查詢 if (this.targetBeanName == null) { this.targetBeanName = getFilterName(); } // Fetch Spring root application context and initialize the delegate early, // if possible. If the root application context will be started after this // filter proxy, we'll have to resort to lazy initialization. WebApplicationContext wac = findWebApplicationContext(); if (wac != null) { //從Spring容器中獲取注入的Filter的實現類 this.delegate = initDelegate(wac); } } } } protected Filter initDelegate(WebApplicationContext wac) throws ServletException { //從Spring 容器中獲取注入的Filter的實現類 Filter delegate = wac.getBean(getTargetBeanName(), Filter.class); if (isTargetFilterLifecycle()) { delegate.init(getFilterConfig()); } return delegate; }
2、在DelegatingFilterProxy的實現方法doFilter中,其實最終呼叫的是委派的類delegate
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { // Lazily initialize the delegate if necessary. //獲取委派Filter實現類 Filter delegateToUse = this.delegate; if (delegateToUse == null) { synchronized (this.delegateMonitor) { if (this.delegate == null) { WebApplicationContext wac = findWebApplicationContext(); if (wac == null) { throw new IllegalStateException("No WebApplicationContext found: " + "no ContextLoaderListener or DispatcherServlet registered?"); } this.delegate = initDelegate(wac); } delegateToUse = this.delegate; } } // Let the delegate perform the actual doFilter operation. invokeDelegate(delegateToUse, request, response, filterChain); } //呼叫委派的Filter的doFilter方法 protected void invokeDelegate( Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { delegate.doFilter(request, response, filterChain); }
總結:Spring web通過提高DelegatingProxyFilter類給開發者提供了便利