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
对象的创建。