Look at someone else's code today and configure one such filter in the Web.xml file deployment descriptor:
<filter>
<filter-name>shiroFilter</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>
</filter>
<filter-mapping>
<filter-name>shirofilter</ filter-name>
<url-pattern>/xx/*</url-pattern>
</filter-mapping>
A similar configuration is also used when using springsecurity:
<filter>
<filter-name>springSecurityFilterChain</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>
</filter>
<filter-mapping>
<filter-name> springsecurityfilterchain</filter-name>
<url-pattern>/xx/*</url-pattern>
</ Filter-mapping>
Personally feel that spring-web fried bag underneath this proxy class
main roleAs follows:
Enables filter to use the bean in spring to achieve a pluggable effect. For example, you can use a security framework such as Shiro or springsecurity to manage permissions, which is to decouple the security validation piece from spring.
Specific Process : The Contextloaderlistener in web.xml loads the related configuration files for spring and the Shiro or springsecurity you use, and then initializes the declared Bean, which has the bean used in the filter, so that the filter uses these The bean can be taken in spring's bean container.
The inheritance relationship of the Delegatingfilterproxy is as follows:
And Genericfilterbean implements the following interface:
Public abstract class Genericfilterbean implements
Filter, Beannameaware, Environmentaware, Servletcontextaware, Initializingbean, Disposablebean {...}
Delegatingfilterproxy class extends abstract class Genericfilterbean,implements interface Filter,servlet container at startup, the first invocation of the filter's Init method, Init () Method inherits from the Genericfilterbean class, the main function is to set the initialization parameter of the filter to the filter which inherits from the Genericfilterbean class, and calls the Initfilterbean () that is left to subclass implementation. method to take the bean you want to fit from the context of spring, which is the Shiro bean.
@Override Public final void init (Filterconfig filterconfig) throws Servletexception {Assert.notnull (filterconfig, "Fil
Terconfig must not being null ");
if (logger.isdebugenabled ()) {Logger.debug ("initializing filter" + filterconfig.getfiltername () + "");
} this.filterconfig = Filterconfig;
Set Bean properties from init parameters.
try {propertyvalues PVs = new Filterconfigpropertyvalues (Filterconfig, this.requiredproperties);
Beanwrapper bw = propertyaccessorfactory.forbeanpropertyaccess (this);
Resourceloader Resourceloader = new Servletcontextresourceloader (Filterconfig.getservletcontext ());
Bw.registercustomeditor (Resource.class, New Resourceeditor (Resourceloader, this.environment));
Initbeanwrapper (BW);
Bw.setpropertyvalues (PVs, true); catch (Beansexception ex) {String msg = "Failed to set bean properties on filter" + filterconfig.ge
Tfiltername () + "':" + ex.getmessage (); Logger.error(msg, ex);
throw new Nestedservletexception (MSG, ex);
}//Let subclasses does whatever initialization they like.Initfilterbean ();if (logger.isdebugenabled ()) {Logger.debug ("Filter" + filterconfig.getfiltername () + "' configured successfully")
; }
}
/**
* Subclasses may override this to perform custom initialization.
* All beans properties of this filter would have been set before this
* to be invoked.
* <p>note:this method is called from standard filter initialization * As as the
filter Bean Initializatio N in a Spring application the context.
* Filter name and ServletContext is available in both cases.
* <p>this default implementation is empty.
* @throws Servletexception If subclass initialization fails
* @see #getFilterName ()
* @see #getServletContext ( )
*
/protected void Initfilterbean () throws servletexception {
}
The following Delegatingfilterproxy Initfilterbean () implementation:
@Override
protected void Initfilterbean () throws Servletexception {
synchronized (this.delegatemonitor) {
if (this.delegate = = null) {
//If no target bean name specified, use filter name
. if (This.targetbeanname = = null) {
this.targetbeanname = Getfiltername ();
}
Fetch Spring Root Application context and initialize the delegate early,
//if possible. If the root application context'll be started on this
//filter proxy, we'll have to resort to lazy Initializatio N.
Webapplicationcontext WAC = Findwebapplicationcontext ();
if (WAC!= null) {
this.delegate = initdelegate (WAC);}}}}
Delegatingfilterproxy rewrite the method to make the use of the filter name you configured to skim the spring context for the filterbean you introduced.
, set to the This.delegate property of this class, to wait for the delegate call to be requested.
We all know that the main method of a filter is Dofilter (...), let's take a look at this method of the Delegatingfilterproxy class:
@Override public void Dofilter (ServletRequest request, servletresponse response, Filterchain filterchain) throw
S servletexception, IOException {//lazily initialize the delegate if necessary.
Filter delegatetouse = this.delegate;
if (Delegatetouse = = null) {synchronized (this.delegatemonitor) {if (this.delegate = = null) { Webapplicationcontext WAC = Findwebapplicationcontext ();//Get Spring context if (WAC = = null) {throw New IllegalStateException ("No Webapplicationcontext Found:" + "no Contextloaderlistener or Dispatch
Erservlet registered? ");}
This.delegate = Initdelegate (WAC)//Initialize delegate, which is the filterbean of the security framework that you introduced in the end () Delegatetouse = this.delegate;
}//Let the delegate perform the actual dofilter operation. Invokedelegate (Delegatetouse, request, response, filterchain);//finally Invoke the Dofilter () method of the filter that actually you introduced
When setting shirofilter, there is a property called Targetfilterlifecycle, which defaults to false. The purpose of this property is to enable the Init () and Destry () methods that introduce the filter. The code is as follows:
/**
* Initialize The Filter delegate, defined as bean the given Spring
* Application context.
* <p>the default implementation fetches the bean from the application context
* and calls the standard {@code Fi Lter.init} method on it, passing * in the filterconfig of this
Filter proxy.
* @param WAC the root application context
* @return the initialized delegate Filter
* @throws servletexception if Thrown by the Filter
* @see #getTargetBeanName () *
@see #isTargetFilterLifecycle () *
@see #getFilterConfig ()
* @see javax.servlet.filter#init (javax.servlet.FilterConfig)
/
protected Filter initdelegate ( Webapplicationcontext WAC) throws servletexception {
Filter delegate = Wac.getbean (Gettargetbeanname (), Filter.class);
if (Istargetfilterlifecycle ()) {//If true, invokes the initialization method of the introduced filter, that is, the Shirofilter init () method
Delegate.init ( Getfilterconfig ());
}
return delegate;
}
Time is limited, writing is a bit messy.