使用springboot自动配置源码解读
作者:阿胜yss
自动装配是Spring Boot的一个核心特性,允许程序员在开发中更加专注于业务逻辑,而不是花费大量的时间去配置和管理第三方组件,当开发者在pom.xml文件中添加了某个依赖后,Spring Boot通过自动配置的方式,将这些第三方组件的实例自动注入到IOC容器中
什么是自动装配
当我们程序依赖第三方功能组件时,不需要手动将这些组件类加载到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); }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。