SpringBoot:自动化装配功能(@SpringBootApplication注解详解)

SpringBoot:自动化装配功能(@SpringBootApplication注解详解)

一、@SpringBootApplication实际是@SpringBootConfiguration,@EnableAutoConfiguration以及@ComponentScan的组合。

1.1、@SpringBootConfiguration而@Configuration有相同的作用,加上这个注解就是为了让当前类作为一个配置类交由 Spring 的 IOC 容器进行管理。
1.2、@ComponentScan注解完成的是自动扫描的功能,相当于Spring XML配置文件中的。如果不设置的话默认扫描@ComponentScan注解所在类的同级类和同级目录下的所有类,所以对于一个Spring Boot项目,一般会把入口类放在顶层目录中,这样就能够保证源码目录下的所有类都能够被扫描到。

1.3、@EnableAutoConfiguration(核心)。

1.3.1、@AutoConfigurationPackage

AutoConfigurationPackage注解的作用是将添加该注解的类所在的package作为自动配置package进行管理。

@AutoConfigurationPackage里面主要的配置@Import({AutoConfigurationPackages.Registrar.class}),跟进Registrar.class。

   static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        Registrar() {
        }

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            AutoConfigurationPackages.register(registry, (String[])(new PackageImports(metadata)).getPackageNames().toArray(new String[0]));
        }

        public Set determineImports(AnnotationMetadata metadata) {
            return Collections.singleton(new PackageImports(metadata));
        }
    }
 
  

从注释中可以看出,它的功能简单说就是将应用的 package给注册到Spring容器中。

1.3.2、@Import({AutoConfigurationImportSelector.class}),跟进到以下:

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationEntry(configurations, exclusions);
        }
    }
  protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }
 protected Class getSpringFactoriesLoaderFactoryClass() {
        return EnableAutoConfiguration.class;
    }
@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 {};
}

loadFactoryNames 方法会去 META-INF/spring.factories 文件中根据 EnableAutoConfiguration 的全限定类名获取到我们需要导入的类,而 EnableAutoConfiguration 类的全限定类名为org.springframework.boot.autoconfigure.EnableAutoConfiguration。当我们启动 SpringBoot 项目的时候,SpringBoot 会扫描所有 jar 包下面的 META-INF/spring.factories 文件,并根据 key 值进行读取,最后在经过去重等一些列操作得到了需要自动装配的类。

你可能感兴趣的:(源码解析,spring,boot,自动化,java)