spring-boot项目的特色就在于它的自动配置,自动配置就是开箱即用的本源。
不过支持一个子项目的自动配置,往往比较复杂,无论是sping自己的项目,还是第三方的,都是如此。刚接触会有点乱乱的感觉。简单记录一下:
首先,要用注解引入一个功能,这个注解的命名格式往往是 Enable + 功能名。比如,EnableAuthorizationServer,要在基于spring框架的项目中引入OAuth2的授权服务器功能,需要在@Configuration注解的类上加入@EnableAuthorizationServer。
第二步,跟着Enable注解引入的往往是需要真正被配置的的类,这些类往往是功能名 + Configuration,比如@EnableAuthorizationServer引入了AuthorizationServerEndpointsConfiguration和AuthorizationServerSecurityConfiguration,这两个类才是配置的核心所在。
第三步:与xxxConfiguration相对应的是xxxConfigurer,这些Configurer将是暴露出来给使用框架的开发者,用它来自定义Configuration中的对象或参数进行自定义。然后Configuration类的做法往往是这样的,使用spring的DI机制,将BeanFactory容器中所有的xxxConfigure注入到一个队列中,然后将队列中的所有xxxConfigure的配置方法回调一下,达到最终配置的目的。 比如:
@Autowired
private List<AuthorizationServerConfigurer> configurers = Collections.emptyList();
当上面自动注入了之后,将做下面的事情:
@PostConstruct
public void init() {
for (AuthorizationServerConfigurer configurer : configurers) {
try {
configurer.configure(endpoints);
} catch (Exception e) {
throw new IllegalStateException("Cannot configure enpdoints", e);
}
}
endpoints.setClientDetailsService(clientDetailsService);
}
关于这一步,记住真正被需要的完成最终系统功能的对象都在xxxConfiguration中了。
第四步:为了方便xxxCofigure对某些特定类进行配置,常常会引入xxxBuilder。看看这Builder源码或许会发现代码绕来绕去的,但是Builder目的明确,就是构建某个类的对象中的属性值,记住这一点就可以了。另外对于xxxConfigure也需要记住一点,就是所有需要给配置的参数或者参数对象,都会列在xxxConfigure中,如果这里面没有你需要配置的参数,那就要想点其它方法了,比如用spring自带的代理机制。
第五步:到这里还没有自动配置什么事儿,其实自动配置也就是众多Configure中的一个,只不过它设定了所有需要参数的默认值。也因为这个原因,自动配置可以被其它配置改写或者顶替掉自动配置。自动配置常常被命名为xxxAutoConfiguration,比如OAuth2AutoConfiguration。
综上所述,spring-boot项目中,其实是以@Enablexxx注解驱动某个功能,然后以xxxAutoConfiguration来填充默认值,如此就能保证这个功能以最基本的要求运行起来。而改变其中的默认行为,则需要通过定义xxxConfigure来完成。