Spring web在設計的時候考慮到某些功能的實作是通過Filter來攔截進行實作的,如果直接的簡單的實作幾個Filter好像也不是不可以(平時我們就是這麼用的),但是Spring架構最核心的是IOC容器,和Spring架構最好的實作就是将要實作的Filter功能注冊到IOC容器的一個Bean,這樣就可以和Spring IOC容器進行完美的融合,是以Spring Web設計了DelegatingFilterProxy。本質上來說DelegatingFilterProxy就是一個Filter,其間接實作了Filter接口,但是在doFilter中其實調用的從Spring 容器中擷取到的代理Filter的實作類delegate。
@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;
}
@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);
}