springBoot自动装配做什么?
把 java bean 注册到 spring Ioc 容器中,但不是程序员自己写 @Bean 等方式进行注册,而是整合了 springBoot 组件框架后,会把一些约定好的 java bean , 在程序项目启动(服务启动)时候自行进行注册,如数据库配置 。
不同的模块定义一些自动的启动类,这些启动类结合 application.yml 配置文件生效,实现 java bean 的注册到 spring Ioc 。 注册之后在程序中可以直接注入使用(如采用 @Autowired 注入)。
定制的组件,也可以采用此种方式进行注册 。
实现方式,采用 spring-boot-xxx-start 方式。
springBoot的思想
约定优于配置
实现方式
形式 : 启动类(@EnableXxx) + 配置( application.yml 、XxxAutoConfiguration 配置类)+ spring.factory 。
原理 : spring 的 java bean 注册,@Bean 、 @Import 注解形式、 @Selector 等8种 方式。把要自动装配的 XxxAutoConfiguration 放到 spring.factory 中。项目启动时候 spring Ioc 会自动处理 spring.factory 中指定的自动装配类。
spring boot 组件,提供了很多自动装配的注解, 结合 spring 的 java bean 注入方式完成对配置类进行自动注册。spring 和 spring boot 提供的如下如下(部分):
// 如下是 spring 的注解
org.springframework.context.annotation.Configuration // srping 配置类 注解
org.springframework.context.annotation.Conditional // spring 条件注入 注解
org.springframework.context.annotation.Import // spring 注入 java bean 注解
// 如下是 spring boot 提供的注解
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
org.springframework.boot.context.properties.EnableConfigurationProperties
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
org.springframework.boot.context.properties.EnableConfigurationPropertiesRegistrar
案例分析:
spring cloud feign start
具体实现原理
@EnableConfigurationProperties
1、 org.springframework.boot.context.properties.EnableConfigurationProperties 注解
该注解的作用就是让要注入到 spring Ioc 容器中的 java bean (假设这个 java bean 是 T) 取到配置文件中的配置的属性值。注解源码如下 :
package org.springframework.boot.context.properties;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesRegistrar.class)
public @interface EnableConfigurationProperties {
String VALIDATOR_BEAN_NAME = "configurationPropertiesValidator";
Class<?>[] value() default {}; //
}
2、 取到配置文件中(application.ympl)的属性赋值给 java bean ,然后借助 @Import 注解把需要 EnableConfigurationPropertiesRegistrar 注册到 spring Ioc 容器 。
3、EnableConfigurationPropertiesRegistrar 类,它实现了 spring 的 ImportBeanDefinitionRegistrar 接口,源码如下:
package org.springframework.boot.context.properties;
class EnableConfigurationPropertiesRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
registerInfrastructureBeans(registry);
ConfigurationPropertiesBeanRegistrar beanRegistrar = new ConfigurationPropertiesBeanRegistrar(registry);
getTypes(metadata).forEach(beanRegistrar::register);
}
private Set<Class<?>> getTypes(AnnotationMetadata metadata) {
return metadata.getAnnotations().stream(EnableConfigurationProperties.class)
.flatMap((annotation) -> Arrays.stream(annotation.getClassArray(MergedAnnotation.VALUE)))
.filter((type) -> void.class != type).collect(Collectors.toSet());
}
@SuppressWarnings("deprecation")
static void registerInfrastructureBeans(BeanDefinitionRegistry registry) {
ConfigurationPropertiesBindingPostProcessor.register(registry);
ConfigurationPropertiesBeanDefinitionValidator.register(registry);
ConfigurationBeanFactoryMetadata.register(registry);
}
}
@Import 注解
@Import 注解是将 java bean 注册到 spring Ioc 容器中。
@Import 注解有一个作用(还有其他注册方式),可以把实现了 ImportBeanDefinitionRegistrar 接口的类注册到 spring Ioc 容器中。
@Import 注解的几个导入方式如下:
1、类导入
最简单的注入方式,直接指定要注入的类,如下:
@Import(T.class)
2、ImportSelector 导入
要注入的类有很多,如果按照类导入方式,要写很多。可以把要注入的这些类都放到 XxxSelector 中,这样会把在 XxxSelector 中的类都注册到 spring Ioc 容器。
public class XxxSelector implements ImportSelector {
//
}
3、ImportBeanDefinitionRegistrar 导入 1和2 java bean 的创建都是 spring Ioc 容器完成,如果要注册的 java bean 有一些业务逻辑,则可以使用 ImportBeanDefinitionRegistrar 导入。
让application.ympl在配置时候能给一些提示
// TODO 2022-6-10