springBoot自动装配原理分析

2020-04-24  本文已影响0人  剑道_7ffc

什么是 springboot

springBoot是服务于框架的框架,利用"约定优于配置"来简化配置文件。

快速创建一个web的springBoot

1 选择Spring initializr
2 选中web->web

约定优于配置的体现

1 maven 的目录结构
默认有 resources 文件夹存放配置文件
默认打包方式为 jar
2 spring-boot-starter-web 中默认包含 spring mvc 相关依赖以及内置的 tomcat 容器
3 默认提供 application.properties/yml 文件
4 默认通过 spring.profiles.active 属性来决定运行环境时读取的配置文件
5 EnableAutoConfiguration 默认对于依赖的 starter 进行自动装载

SpringBootApplication注解

SpringBootApplication是ComponentScan,SpringBootConfiguration和
EnableAutoConfiguration的复合注解

ComponentScan

类似于<context:component-scan>用来配置扫描的类,若不配置值,则默认扫描类所在的包名。

SpringBootConfiguration

SpringBootConfiguration是Configuration,Configuration是用来表示表明java是一种配置类,可以用来替换xml配置文件。

EnableAutoConfiguration

EnableAutoConfiguration是Import和AutoConfigurationPackage的复合注解。

Import

Import就是配置文件的<import/>,将多个配置文件合并为一个配置文件。
@Import可以配置的三种类
1 被Configuration修饰的类
2 实现 ImportSelector 接口进行if判断的动态注入
3 实现 ImportBeanDefinitionRegistrar 接口进行if判断的动态注入

AutoConfigurationPackage

AutoConfigurationPackage也是import

SpringFactoriesLoader

SpringFactoriesLoader原理和spi相同,不同的是spi是一次性加载,而SpringFactoriesLoader根据key进行加载。作用是从classpath/META-INF/spring.factories文件中,根据key来加载对应的类到spring ioc容器中。
主要场景是将其他jar中的bean自动装配到ioc容器中。

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

    Enumeration<URL> 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;
}

条件过滤

默认的配置文件是classpath/META-INF/spring-autoconfigure-metadata.properties,场景是根据依赖对应的类,来判断是否加载对应的类。源码如下

class AutoConfigurationMetadataLoader {
    protected static final String PATH = "META-INF/" + "spring-autoconfigure-metadata.properties";

    public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
            return loadMetadata(classLoader, PATH);
    }

    static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
        Enumeration<URL> urls = (classLoader != null) ?      
            classLoader.getResources(path) : 
            ClassLoader.getSystemResources(path);
        Properties properties = new Properties();
        while (urls.hasMoreElements()) {
            properties.putAll(PropertiesLoaderUtils.loadProperties(newUrlResource(urls .nextElement())));
        }
        return loadMetadata(properties);
    }
}

Conditional 中的其他注解

image.png
上一篇下一篇

猜你喜欢

热点阅读