做vlogger的网站有哪些,海南省住房和城乡建设厅官网网站首页,做旅游攻略的网站好,饲料网站源码一、前言
本章主要内容是关于配置器的接口架构设计#xff0c;任意找一个配置器一直往上找#xff0c;就会找到配置器的顶级接口#xff1a;SecurityConfigurer。
查看SecurityConfigurer接口的实现类情况#xff1a; 在 AbstractHttpConfigurer 抽象类的下面可以看到所有…一、前言
本章主要内容是关于配置器的接口架构设计任意找一个配置器一直往上找就会找到配置器的顶级接口SecurityConfigurer。
查看SecurityConfigurer接口的实现类情况 在 AbstractHttpConfigurer 抽象类的下面可以看到所有用来配置 HttpSecurity 的配置器实现类也是构造器。 再通过继承关系图看看配置器顶层的架构 会发现其中SecurityConfigurerAdapter和GlobalAuthenticationConfigurerAdapter对SecurityConfigurer接口进行了实现而WebSecurityConfigurer对SecurityConfigurer接口进行了继承。
查看SecurityConfigurer源码: 源码注释 Allows for configuring a SecurityBuilder. All SecurityConfigurer first have their init(SecurityBuilder) method invoked. After all init(SecurityBuilder) methods have been invoked, each configure(SecurityBuilder) method is invoked. 允许配置SecurityBuilder构造器。所有SecurityConfigurer首先调用其init(SecurityBuilderr) 方法。在调用了所有init(SecurityBuilderr) 方法之后将调用每个configure(SecurityBuilderr) 方法。 请参阅: AbstractConfiguredSecurityBuilder 作者: Rob Winch 类型形参: O – The object being built by the SecurityBuilder B O 是被 B继承SecurityBuilderO的构造器构造出来的对象类型 B – The SecurityBuilder that builds objects of type O. This is also the SecurityBuilder that is being configured B 是被构造对象类型O的构造器类型也是正在配置的构造器。 特殊说明 SecurityConfigurer 的所有实现类都是用来配置构造器的。也就是说泛型中 O 和 B 的关系是B 用来构造 O。而配置器的作用是配置这个构造器的从而影响最终构造的结果。 /*** Allows for configuring a {link SecurityBuilder}. All {link SecurityConfigurer} first* have their {link #init(SecurityBuilder)} method invoked. After all* {link #init(SecurityBuilder)} methods have been invoked, each* {link #configure(SecurityBuilder)} method is invoked.** param O The object being built by the {link SecurityBuilder} B* param B The {link SecurityBuilder} that builds objects of type O. This is also the* {link SecurityBuilder} that is being configured.* author Rob Winch* see AbstractConfiguredSecurityBuilder*/
public interface SecurityConfigurerO, B extends SecurityBuilderO {/*** Initialize the {link SecurityBuilder}. Here only shared state should be created* and modified, but not properties on the {link SecurityBuilder} used for building* the object. This ensures that the {link #configure(SecurityBuilder)} method uses* the correct shared objects when building. Configurers should be applied here.* * 初始化SecurityBuilder构造器。 这里只应该创建和修改共享状态而不是用于构建对象的SecurityBuilder构造器上的属性。* 这可确保 configure(SecurityBuilder)方法在构建时使用正确的共享对象。 应在此处应用配置器。* * param builder* throws Exception*/void init(B builder) throws Exception;/*** Configure the {link SecurityBuilder} by setting the necessary properties on the* * 配置SecurityBuilder构造器必要的属性。* * {link SecurityBuilder}.* param builder* throws Exception*/void configure(B builder) throws Exception;}下面我们分别对SecurityConfigurerAdapter、GlobalAuthenticationConfigurerAdapter、WebSecurityConfigurer三个分支进行源码分析。
二、SecurityConfigurerAdapter 源码注释 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. SecurityConfigurer的基类它允许子类仅实现它们感兴趣的方法。。它还提供了使用 SecurityConfigurer以及完成后获取正在配置的SecurityBuilder构造器的访问权限的机制。 作者: Rob Winch, Wallace Wadge 类型形参: O – The Object being built by B O 是被 B 构造出来的对象类型 B – The Builder that is building O and is configured by SecurityConfigurerAdapter B 是被构造对象类型O的构造器同时也是此 SecurityConfigurerAdapter正在配置的对象。 /*** A base class for {link SecurityConfigurer} that allows subclasses to only implement* the methods they are interested in. It also provides a mechanism for using the* {link SecurityConfigurer} and when done gaining access to the {link SecurityBuilder}* that is being configured.** param O The Object being built by B* param B The Builder that is building O and is configured by* {link SecurityConfigurerAdapter}* author Rob Winch* author Wallace Wadge*/
public abstract class SecurityConfigurerAdapterO, B extends SecurityBuilderO implements SecurityConfigurerO, B {private B securityBuilder;private CompositeObjectPostProcessor objectPostProcessor new CompositeObjectPostProcessor();Overridepublic void init(B builder) throws Exception {}Overridepublic void configure(B builder) throws Exception {}/*** Return the {link SecurityBuilder} when done using the {link SecurityConfigurer}.* This is useful for method chaining.* return the {link SecurityBuilder} for further customizations* deprecated For removal in 7.0. Use the lambda based configuration instead.*/Deprecated(since 6.1, forRemoval true)public B and() {return getBuilder();}/*** Gets the {link SecurityBuilder}. Cannot be null.* return the {link SecurityBuilder}* throws IllegalStateException if {link SecurityBuilder} is null*/protected final B getBuilder() {Assert.state(this.securityBuilder ! null, securityBuilder cannot be null);return this.securityBuilder;}/*** Performs post processing of an object. The default is to delegate to the* {link 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 {link ObjectPostProcessor} to be used for this* {link SecurityConfigurerAdapter}. The default implementation does nothing to the* object.* param objectPostProcessor the {link ObjectPostProcessor} to use*/public void addObjectPostProcessor(ObjectPostProcessor? objectPostProcessor) {this.objectPostProcessor.addObjectPostProcessor(objectPostProcessor);}/*** Sets the {link SecurityBuilder} to be used. This is automatically set when using* {link AbstractConfiguredSecurityBuilder#apply(SecurityConfigurerAdapter)}* param builder the {link SecurityBuilder} to set*/public void setBuilder(B builder) {this.securityBuilder builder;}/*** An {link ObjectPostProcessor} that delegates work to numerous* {link ObjectPostProcessor} implementations.** author Rob Winch*/private static final class CompositeObjectPostProcessor implements ObjectPostProcessorObject {private ListObjectPostProcessor? postProcessors new ArrayList();OverrideSuppressWarnings({ rawtypes, unchecked })public Object postProcess(Object object) {for (ObjectPostProcessor opp : this.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 {link ObjectPostProcessor} to use* param objectPostProcessor the {link ObjectPostProcessor} to add* return true if the {link ObjectPostProcessor} was added, else false*/private boolean addObjectPostProcessor(ObjectPostProcessor? objectPostProcessor) {boolean result this.postProcessors.add(objectPostProcessor);this.postProcessors.sort(AnnotationAwareOrderComparator.INSTANCE);return result;}}}内容很简单 有一个内部类CompositeObjectPostProcessor复合后置处理器对象类 定义了两个成员变量 将要配置的构造器 securityBuilder复合后置处理器 objectPostProcessor 从接口中实现的方法和自己新加的几个方法 init 和 configure 是实现接口的方法and、getBuilder、postProcess、addObjectPostProcessor、setBuilder 方法是自己加的
2.1 允许子类只实现他们感兴趣的方法
在源码中可以看到所有的方法都有方法体包括对接口方法的实现虽然是空方法体。所以继承 SecurityConfigurerAdapter 的配置器可以根据自己的需求实现覆盖自己感兴趣的方法。 可以自己实现 init 如果自己不需要初始化也可以不实现在构造器调用其 init 方法时什么也不做。 2.2 setBuilder 方法
这个方法有点特别所以单独说一下方法内容很简单就是设置配置器的成员变量private B securityBuilder即构造器但是官网又这样一句注释 Sets the SecurityBuilder to be used. This is automatically set when using AbstractConfiguredSecurityBuilder.apply(SecurityConfigurerAdapter) 第一句很好理解这个方法是来设置要使用的构造器private B securityBuilder其B extends SecurityBuilderO。
第二句就是当 AbstractConfiguredSecurityBuilder.apply(SecurityConfigurerAdapter) 调用时被自动设置。
回顾上篇中的4.4.7章节
/*** Applies a {link SecurityConfigurerAdapter} to this {link SecurityBuilder} and* invokes {link SecurityConfigurerAdapter#setBuilder(SecurityBuilder)}.* param configurer* return the {link SecurityConfigurerAdapter} for further customizations* throws Exception*/
SuppressWarnings(unchecked)
public C extends SecurityConfigurerAdapterO, B C apply(C configurer) throws Exception {configurer.addObjectPostProcessor(this.objectPostProcessor);configurer.setBuilder((B) this);add(configurer);return configurer;
}可以看出configurer在被调用之前是不知道要配置哪个构造器的。在构造器调用 apply 方法时才真正设置配置器的成员变量即构造器。所以官方注释才说 setBuilder 方法时自动调用的我们不能手动去设置。 只有构造器(B) this应用了这个配置器configurer这个配置器configurer才会绑定上这个构造器(B) this。 2.3 and 方法
and() 方法提供了一种使用SecurityConfigurer以及完成后获取正在配置的SecurityBuilder构造器的访问权限的机制。
有必要说一下为什么是正在配置因为在这个时候还没有对构造器private B securityBuilder 进行配置。
在上篇文章中讲解Builder设计模式时提到过构造器的构造时机在调用构造器的 build 方法在AbstractConfiguredSecurityBuilder#doBuild方法中加入了构造生命周期控制在里面才开始调用各个配置器的 init 方法和 configure 方法。所以这里获取到的时正在配置的构造器对象。 在构造器的构造过程中利用配置器进行配置从而影响最终构造的结果。 2.4 复合后置处理对象
这个内部类对象很简单看一下内部类的内容就明白了它维护的是一个 List 集合
private ListObjectPostProcessor? postProcessors new ArrayList();因此称之为复合后置处理对象CompositeObjectPostProcessor就是里面有多个。
2.5 DEBUG 参数跟踪
AbstractConfiguredSecurityBuilder#apply SecurityConfigurerAdapter#setBuilder 由上可知 SecurityConfigurerAdapter中设置的构造器为HttpSecurity。 三、GlobalAuthenticationConfigurerAdapter
这个类的类名说明它是一个全局配置相关的类。
/*** A {link SecurityConfigurer} that can be exposed as a bean to configure the global* {link AuthenticationManagerBuilder}. Beans of this type are automatically used by* {link AuthenticationConfiguration} to configure the global* {link AuthenticationManagerBuilder}.** author Rob Winch* since 5.0*/
Order(100)
public abstract class GlobalAuthenticationConfigurerAdapterimplements SecurityConfigurerAuthenticationManager, AuthenticationManagerBuilder {Overridepublic void init(AuthenticationManagerBuilder auth) throws Exception {}Overridepublic void configure(AuthenticationManagerBuilder auth) throws Exception {}}从源码可以看出它实现 SecurityConfigurer 接口没有具体的实现内容只是对构造器和构造器将要构造的对象做了限制 将要配置的构造器AuthenticationManagerBuilder 可以作为bean公开以配置全局构造器AuthenticationManagerBuilder。 将要构造的对象AuthenticationManager 将被构造器构造出最终目的类型AuthenticationManager。
四、WebSecurityConfigurer
/*** Allows customization to the {link WebSecurity}. In most instances users will use* {link EnableWebSecurity} and create a {link Configuration} that exposes a* {link SecurityFilterChain} bean. This will automatically be applied to the* {link WebSecurity} by the {link EnableWebSecurity} annotation.** author Rob Winch* since 3.2* see SecurityFilterChain*/
public interface WebSecurityConfigurerT extends SecurityBuilderFilter extends SecurityConfigurerFilter, T {}该接口继承SecurityConfigurer接口从源码中可以看出它没有定义自己的方法所有的方法都是从父接口继承那么它的作用还有配置SecurityBuilder构造器但是它对类型做了约束 WebSecurityConfigurer 的泛型为 T T继承了SecurityBuilder所以T表示是一个对象构造器 SecurityBuilder的泛型为Filter 表示 SecurityBuilder 将要构造的对象是一个 javax.servet.Filter也就是说它约束了T说明T的作用是构造Filter 将要传入父接口SecurityConfigurer的两个泛型Filter和 T WebSecurityConfigurer 继承 SecurityConfigurer从这里可以看出对SecurityConfigurer做了约束目前只有T还没有指定具体的类型至于最终使用什么类型的构造器由实现类或者子接口指定。