springBoot自动装配原理分析
什么是 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);
}
}