如何写一个给自己的框架写一个优雅的Java Config模块(一)
原创
©著作权归作者所有:来自51CTO博客作者陈振阳Plus的原创作品,请联系作者获取转载授权,否则将追究法律责任
Build设计模式
配置模块化
用build设计模式将配置模块化。
配置的依赖关系管理
主从模式
可以暂时先看下面的主从从模式。
单属性配置
httpSecurity.authorizeRequests().regexMatchers("/url/**").authenticated().regexMatchers("/url2/**").anonymous();
上边的代码authorizeRequests方法返回的是一个ExpressionUrlAuthorizationConfigurer对象,regexMatchers方法返回一个AuthorizedUrl对象,这个对象有很多设置权限的方法,但是这个对象的所有方法能且只能被调用一次。Spring Security用来控制只能被调用一次的方法就是不管调用AuthorizedUrl对象的哪个方法,接着返回ExpressionUrlAuthorizationConfigurer对象。
主从从模式
httpSecurity.sessionManagement().maximumSessions(10).expiredUrl("someurl").and().sessionFixation();
上边的代码分解如下:
SessionManagementConfigurer<HttpSecurity> sessionManagementConfigurer = httpSecurity.sessionManagement();
ConcurrencyControlConfigurer concurrencyControlConfigurer = sessionManagementConfigurer.maximumSessions(10);
concurrencyControlConfigurer = concurrencyControlConfigurer.expiredUrl("someurl");
sessionManagementConfigurer = concurrencyControlConfigurer.and();
sessionManagementConfigurer.sessionFixation();
要有从任何一个子模块回到上一个模块的方式。
使用泛型配置配置的依赖关系
正确使用泛型,可以让一个子模块同时配置到多个类似的父模块。
<http>
<cors configuration-source-ref="test" ref="test"/>
</http>
<cors configuration-source-ref="test" ref="test"/>
如上,cors这个配置可以同时存在于两个不同的父元素中。
Spring Security中使用了大量的泛型很好的处理了这个问题。
public class CorsConfigurer<H extends HttpSecurityBuilder<H>>
extends AbstractHttpConfigurer<CorsConfigurer<H>, H>
public abstract class AbstractHttpConfigurer<T extends AbstractHttpConfigurer<T, B>, B extends HttpSecurityBuilder<B>>
extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, B>
public abstract class SecurityConfigurerAdapter<O, B extends SecurityBuilder<O>>
implements SecurityConfigurer<O, B>
build方法的正确姿势(init,configure)
特定位置预留扩展点,同时提供构建状态的信息。
public final O build() throws Exception {
if (this.building.compareAndSet(false, true)) {
this.object = doBuild();
return this.object;
}
throw new AlreadyBuiltException("This object has already been built");
}
protected final O doBuild() throws Exception {
synchronized (configurers) {
buildState = BuildState.INITIALIZING;
beforeInit();
init();
buildState = BuildState.CONFIGURING;
beforeConfigure();
configure();
buildState = BuildState.BUILDING;
O result = performBuild();
buildState = BuildState.BUILT;
return result;
}
}
运行时信息
可以直接看Spring Security之Builder sharedObjects这篇文章。
与框架或者中间件的非配置模块交互的正确姿势
//TODO
提供一个配置适配器供用户继承重载
类似Spring Security的WebSecurityConfigurerAdapter,在里面提供的内容如下:
- 各个配置项的默认配置
- 顶级配置项的配置重载回调方法
- 重要配置项的配置方法,比如各种顶级概念的bean