springboot如何自动装配

1.启动装配入口

XxxxApplication

package com.example.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//关键注解, 自动注入的关键
@SpringBootApplication
public class SpringbootApplication {


    public static void main(String[] args) {
        //run方法, springboot启动入口, 解释注解, 加载配置
        SpringApplication.run(SpringbootApplication.class, args);
    }

}

2.@SpringBootApplication

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration    //标识为配置类
@EnableAutoConfiguration  // 启动自动注入配置☆☆☆☆该处为自动装配关键
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
//.........省略内容
}

3.@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage    
@Import(AutoConfigurationImportSelector.class)    //关键注解, 导入AutoConfigurationImportSelector类, 该类中关键方法org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports
public @interface EnableAutoConfiguration {
//.........省略内容
}

4.org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports

@Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
                .loadMetadata(this.beanClassLoader);
          //自动注入的Entry
        AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
                autoConfigurationMetadata, annotationMetadata);
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations
-->
org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames
-->
org.springframework.core.io.support.SpringFactoriesLoader#loadSpringFactories

private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap result = cache.get(classLoader);
        if (result != null) {
            return result;
        }

        try {
            //加载自动装配类所处位置FACTORIES_RESOURCE_LOCATION  --> META-INF/spring.factories
            Enumeration urls = (classLoader != null ?
                    classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
            result = new LinkedMultiValueMap<>();
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                for (Map.Entry entry : properties.entrySet()) {
                    String factoryClassName = ((String) entry.getKey()).trim();
                    for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
                        result.add(factoryClassName, factoryName.trim());
                    }
                }
            }
            cache.put(classLoader, result);
            return result;
        }
        catch (IOException ex) {
            throw new IllegalArgumentException("Unable to load factories from location [" +
                    FACTORIES_RESOURCE_LOCATION + "]", ex);
        }
    }

5.META-INF/spring.factories

自动装配的类全名

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\

6.不是所有spring.factories的类都加载

例如:

@Configuration
//@ConditionalOnClass 存在这些类才加载, 否则不加载, 没有加入依赖, 以下类都是未导入的
@ConditionalOnClass({ MongoClient.class, com.mongodb.client.MongoClient.class,
        MongoTemplate.class })
@Conditional(AnyMongoClientAvailable.class)
@EnableConfigurationProperties(MongoProperties.class)
@Import(MongoDataConfiguration.class)
@AutoConfigureAfter(MongoAutoConfiguration.class)
public class MongoDataAutoConfiguration {

    private final MongoProperties properties;

    public MongoDataAutoConfiguration(MongoProperties properties) {
        this.properties = properties;
    }

    @Bean
    @ConditionalOnMissingBean(MongoDbFactory.class)
    public MongoDbFactorySupport mongoDbFactory(ObjectProvider mongo,
            ObjectProvider mongoClient) {
        MongoClient preferredClient = mongo.getIfAvailable();
        if (preferredClient != null) {
            return new SimpleMongoDbFactory(preferredClient,
                    this.properties.getMongoClientDatabase());
        }
        com.mongodb.client.MongoClient fallbackClient = mongoClient.getIfAvailable();
        if (fallbackClient != null) {
            return new SimpleMongoClientDbFactory(fallbackClient,
                    this.properties.getMongoClientDatabase());
        }
        throw new IllegalStateException("Expected to find at least one MongoDB client.");
    }
//......省略内容

你可能感兴趣的:(springboot如何自动装配)