开发者

使用springboot自动配置源码解读

目录
  • 什么是自动装配
  • @SpringBootApplication 作用
    • @EnableAutoConfiguration
  • 源码解读
    • @AutoConfigurationPackage
    • @Import(AutoConfigurationImportSelector.class)
  • 总结

    什么是自动装配

    当我们程序依赖第三方功能组件时,不需要手动将这些组件类加载到IOC容器中。

    例如 当程序需要用到Redis时,在pom.XML文件中引入依赖,然后使用依赖注入的方式直接从IOC容器中拿到相应RedisTemplate实例。

    @SpringBootApplication 作用

    • @SpringBootConfiguration:主启动类可以当做配置类使用,比如注入Bean等。
    • @ComponentScan:包扫描注解。
    • @EnableAutoConfiguration(重要):开启自动配置。

    使用springboot自动配置源码解读

    @EnableAutoConfiguration

    • @AutoConfigurationPackage : 自动配置包注解,默认将主配置python类(@SpringBootAppljavascriptication)所在的包及其子包里面的所有组件扫描到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 {};
    
       javascript 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(ClphpassUtils.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 文件中获取自python动配置类
        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);
    }
    

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜