概述
介绍
SecurityConfigurerAdapter
是Spring Security Config
对概念模型接口SecurityConfigurer
所提供的缺省实现。它作为一个基类存在,开发人员想实现一个SecurityConfigurer
时,可以继承自SecurityConfigurerAdapter
,然后仅仅覆盖实现其中感兴趣的方法。具体来讲,SecurityConfigurerAdapter
提供了如下功能:
SecurityConfigurer
接口所定义的方法的缺省实现#init
#configure
- 设置和获取所要被配置的安全构建器
#setBuilder
#getBuilder
- 设置配置过程中对新建安全对象的后置处理器
#addObjectPostProcessor
- 链式配置构建的支持方法
#and
继承关系
源代码
源代码版本 : Spring Security Config 5.1.4.RELEASE
package org.springframework.security.config.annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
/**
* A base class for SecurityConfigurer that allows subclasses to only implement
* the methods they are interested in. It also provides a mechanism for using the
* SecurityConfigurer and when done gaining access to the SecurityBuilder
* that is being configured.
*
* @author Rob Winch
* @author Wallace Wadge
*
* @param <O> The Object being built by B 构建器B所要构建目标对象
* @param <B> The Builder that is building O and is configured by
* SecurityConfigurerAdapter 构建器
*/
public abstract class SecurityConfigurerAdapter<O, B extends SecurityBuilder<O>>
implements SecurityConfigurer<O, B> {
private B securityBuilder;
// 配置过程中新建的安全对象的后置处理器,该对象是多个ObjectPostProcessor的组合
// 缺省情况下该后置处理器中不包含任何 ObjectPostProcessor
private CompositeObjectPostProcessor objectPostProcessor = new CompositeObjectPostProcessor();
// 空方法,留给子类实现
public void init(B builder) throws Exception {
}
// 空方法,留给子类实现
public void configure(B builder) throws Exception {
}
/**
* Return the SecurityBuilder when done using the SecurityConfigurer.
* This is useful for method chaining.
* 用于支持链式构建,返回目标构建器
* @return the SecurityBuilder for further customizations
*/
public B and() {
return getBuilder();
}
/**
* Gets the SecurityBuilder. Cannot be null.
*
* @return the SecurityBuilder
* @throws IllegalStateException if SecurityBuilder is null
*/
protected final B getBuilder() {
if (securityBuilder == null) {
throw new IllegalStateException("securityBuilder cannot be null");
}
return securityBuilder;
}
/**
* Performs post processing of an object. The default is to delegate to the
* ObjectPostProcessor.
*
* @param object the Object to post process
* @return the possibly modified Object to use
*/
@SuppressWarnings("unchecked")
protected <T> T postProcess(T object) {
return (T) this.objectPostProcessor.postProcess(object);
}
/**
* Adds an ObjectPostProcessor to be used for this
* SecurityConfigurerAdapter. The default implementation does nothing to the
* object.
*
* @param objectPostProcessor the ObjectPostProcessor to use
*/
public void addObjectPostProcessor(ObjectPostProcessor<?> objectPostProcessor) {
this.objectPostProcessor.addObjectPostProcessor(objectPostProcessor);
}
/**
* Sets the SecurityBuilder to be used. This is automatically set when using
* AbstractConfiguredSecurityBuilder#apply(SecurityConfigurerAdapter)
*
* @param builder the SecurityBuilder to set
*/
public void setBuilder(B builder) {
this.securityBuilder = builder;
}
/**
* An ObjectPostProcessor that delegates work to numerous
* ObjectPostProcessor implementations.
*
* 嵌套类,使用组合模式实现了接口 ObjectPostProcessor,用于组合多个 ObjectPostProcessor,
* 当使用该组合对象对目标对象进行后置处理时,其实是使用所组合的每个 ObjectPostProcessor 依次
* 对目标对象进行后置处理
* @author Rob Winch
*/
private static final class CompositeObjectPostProcessor implements
ObjectPostProcessor<Object> {
private List<ObjectPostProcessor<? extends Object>> postProcessors =
new ArrayList<ObjectPostProcessor<?>>();
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object postProcess(Object object) {
for (ObjectPostProcessor opp : postProcessors) {
Class<?> oppClass = opp.getClass();
Class<?> oppType = GenericTypeResolver.resolveTypeArgument(oppClass,
ObjectPostProcessor.class);
if (oppType == null || oppType.isAssignableFrom(object.getClass())) {
object = opp.postProcess(object);
}
}
return object;
}
/**
* Adds an ObjectPostProcessor to use
* @param objectPostProcessor the ObjectPostProcessor to add
* @return true if the ObjectPostProcessor was added, else false
*/
private boolean addObjectPostProcessor(
ObjectPostProcessor<? extends Object> objectPostProcessor) {
boolean result = this.postProcessors.add(objectPostProcessor);
Collections.sort(postProcessors, AnnotationAwareOrderComparator.INSTANCE);
return result;
}
}
}