什么是自动装配
当我们程序依赖第三方功能组件时,不需要手动将这些组件类加载到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注解标注的类所在的包名作为packageNamespackageNames.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);
}
参考 自动配置详解
自动装配代码逐行解读