SPRING与设计模式--策略模式与模板方法模式
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法接口的情况下,重新定义算法的某些步骤。
策略模式定义了算法族,分别封装起来,让他们之间可以互相体会。此模式让算法的变化独立于使用算法的客户。
开源框架为了保证灵活性,方便开发者进行二次开发,经常使用这两种模式。
springsecurity4中身份验证的算法被分割成多个步骤,每个步骤都可以由开发者进行自定义。如果读者需要自己实现定制化的验证方式,那么就可以继承AbstractAuthenticationProcessingFilter,覆盖其中的步骤完成定制化。
身份验证功能由AbstractAuthenticationProcessingFilter实现算法骨架,子类来进行自定义其中的步骤完成最终需要的效果,见类图:
代码中核心的操作步骤见上图,核心源码如下:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (!requiresAuthentication(request, response)) {
chain.doFilter(request, response);
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Request is to process authentication");
}
Authentication authResult;
try {
authResult = attemptAuthentication(request, response);
if (authResult == null) {
// return immediately as subclass has indicated that it hasn't completed
// authentication
return;
}
sessionStrategy.onAuthentication(authResult, request, response);
}
catch (InternalAuthenticationServiceException failed) {
logger.error(
"An internal error occurred while trying to authenticate the user.",
failed);
unsuccessfulAuthentication(request, response, failed);
return;
}
catch (AuthenticationException failed) {
// Authentication failed
unsuccessfulAuthentication(request, response, failed);
return;
}
// Authentication success
if (continueChainBeforeSuccessfulAuthentication) {
chain.doFilter(request, response);
}
successfulAuthentication(request, response, chain, authResult);
}
其中的SessionAuthenticationStrategy使用策略模式,作用描述见源码注释,有两个实现类,见上图
/** * Allows pluggable support for HttpSession-related behaviour when an authentication * occurs. * <p> * Typical use would be to make sure a session exists or to change the session Id to guard * against session-fixation attacks. * * @author Luke Taylor * @since */ public interface SessionAuthenticationStrategy { /** * Performs Http session-related functionality when a new authentication occurs. * * @throws SessionAuthenticationException if it is decided that the authentication is * not allowed for the session. This will typically be because the user has too many * sessions open at once. */ void onAuthentication(Authentication authentication, HttpServletRequest request, HttpServletResponse response) throws SessionAuthenticationException; }