什么是自动装配
当我们程序依赖第三方功能组件时,不需要手动将这些组件类加载到IOC容器中。例如 当程序需要用到redis时,在pom.xml文件中引入依赖,然后使用依赖注入的方式直接从IOC容器中拿到相应RedisTemplate实例。
@SpringBootApplication 作用
- @SpringBootConfiguration:主启动类可以当做配置类使用,比如注入Bean等。
- @ComponentScan:包扫描注解。
- @EnableAutoConfiguration(重要):开启自动配置。
@EnableAutoConfiguration
- @AutoConfigurationPackage : 自动配置包注解,默认将主配置类(@SpringBootApplication)所在的包及其子包里面的所有组件扫描到IOC容器中。
- @Import : 引入相应的自动装配类,这里是导入了AutoConfigurationImportSelector类,从 所有的spring.factories 文件注入自动配置类到IOC容器。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
源码解读
@AutoConfigurationPackage
@Import 引入 Registrar配置类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
PackageImports(AnnotationMetadata metadata) {
// 获取包名
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(AutoConfigurationPackage.class.getName(), false));
List<String> packageNames = new ArrayList(Arrays.asList(attributes.getStringArray("basePackages")));
Class[] var4 = attributes.getClassArray("basePackageClasses");
int var5 = var4.length;
// 获取basePackageClasses属性的属性值,并且对于的包名放入packageNames列表中
for(int var6 = 0; var6 < var5; ++var6) {
Class<?> basePackageClass = var4[var6];
packageNames.add(basePackageClass.getPackage().getName());
}
if (packageNames.isEmpty()) {
// 如果packageNames为空,就将AutoConfigurationPackage注解标注的类所在的包名作为packageNames
packageNames.add(ClassUtils.getPackageName(metadata.getClassName()));
}
this.packageNames = Collections.unmodifiableList(packageNames);
}
@Import(AutoConfigurationImportSelector.class)
直接给到最终代码逻辑 getAutoConfigurationEntry 方法
// 判断是否开启自动配置
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
// 获取注解属性
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
// 从 spring.factories 文件中获取自动配置类
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
// 去掉重复的自动配置类
configurations = this.removeDuplicates(configurations);
// 根据注解配置 排除自动配置类
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
参考 自动配置详解
自动装配代码逐行解读