springboot部分功能浅析
1.绑定器
org.springframework.boot.context.properties.bind.Binder是springboot从environment对象中获取配置信息的绑定器,可以很方便的就获取到对应的配置值信息。
1.创建配置类(必须要提供set方法)
1 |
|
2.配置文件中的配置项
1 | =true |
2.通过Binder获取配置信息
1 | Binder.get(environment).bind("spring.dynamic", Bindable.ofInstance(dtpProperties)); |
2.@Import引入
通过@Import引入将某些配置类或者扩展点接口添加到容器中。
示例:
1.创建一个注解EnableMyConfig,该注解使用@Import标记,并添加MyConfigurationSelector.class,这个类实现了ImportSelector顶层接口。
1 |
|
2.实现DeferredImportSelector#selectImports接口,那么在Spring加载到这个引入类MyConfigurationSelector时就会将MyBeanDefinitionRegistrar类添加到Spring容器中,作用等同于为MyBeanDefinitionRegistrar添加@Component等自动注入注解。
1 | public class MyConfigurationSelector implements DeferredImportSelector, Ordered { |
3.这个引入类一般以注册类居多,如果是配置类一般通过@Component或者@Configuration等注解就可自动注入,我这里的示例是一个注册类。实现于ImportBeanDefinitionRegistrar接口,MyBeanDefinitionRegistrar这个spring生命周期中会执行到registerBeanDefinitions,即为MyProperties类创建BeanDefinition对象,并将这个对象注入到容器中。
1 |
|
注意:@EnableMyConfig注解需要标记到某个类上,且这个类在扫描范围之内才会生效,我曾经深深陷入于这个注解已经是在扫描范围之内,为什么需要标记到某个类上,扫描到这个注解后这个注解不是被@Import标记吗,难道不能直接获取到@Import中的值。实际上还是需要通过标记的这个类上拥有@Component等自动注入的注解。
整个过程大致为:由Spring容器MapperScan入口refresh方法 ⇒执行容器中实现BeanDefinitionRegistryPostProcessor的bean对象⇒ConfigurationClassPostProcessor是对BeanDefinitionRegistryPostProcessor的实现,主要处理逻辑在这个类中。⇒之后会执行实现ImportBeanDefinitionRegistrar#registerBeanDefinitions,也就是这时会执行MyBeanDefinitionRegistrar这个自定义类,在这个自定义类中又注册了新的BeanDefinition⇒之后Spring容器会创建这个Bean对象。
综上:从Spring容器的角度来说,MyBeanDefinitionRegistrar是在ConfigurationClassPostProcessor执行时加载的,MyProperties是在MyBeanDefinitionRegistrar加载之后加载。
目前在Spring的生态中一般都是通过@EnableXX注解标记@Import注解来引入某些配置的方式,进行动态的引入某些配置类。比如EnableScheduling,只有将这个注解标记在扫描配置类之上,才会通过@Import引入配置SchedulingConfiguration类。
1 |
|
@Import也可以配合ImportSelector实现类,进行动态创建类。比如MapperScan。在MapperScannerRegistrar中动态的创建 MapperScannerConfigurer对象并注册到容器中。
1 |
|
3.配置类加载
EnableConfigurationProperties注解配合ConfigurationProperties注解进行使用。
假设说创建了一个配置类:
1 |
|
如果这个类没有标记@Configuration注解,那么这个容器中不会有这个类的Bean对象。
所以将此配置类添加到容器中有两种方式,一种是直接添加注入容器注解@Configuration。第二种是通过@EnableConfigurationProperties注解指向这个配置类。
1 |
|
当加载DtpBaseBeanConfiguration这个类时,会读取到EnableConfigurationProperties注解,这里又是一个@Import的应用,引入了EnableConfigurationPropertiesRegistrar类。
1 | class EnableConfigurationPropertiesRegistrar implements ImportBeanDefinitionRegistrar { |
注意:这个EnableConfigurationProperties注解的作用仅仅是将某个配置类转换为BeanDefinition注册到Spring容器中,结合@ConditionXXX可以减少无用bean对象的创建。