protectedList<String>getCandidateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes){//从指定的配置文件中获取自动配置类(spring-boot-autoconfigure-2.5.6.jar!\META-INF\spring.factories)//以org.springframework.boot.autoconfigure.EnableAutoConfiguration为key对应的所有的value值List<String> configurations =SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),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;}protectedClass<?>getSpringFactoriesLoaderFactoryClass(){returnEnableAutoConfiguration.class;}
SpringFactoriesLoader
publicstaticfinalStringFACTORIES_RESOURCE_LOCATION="META-INF/spring.factories";publicstaticList<String>loadFactoryNames(Class<?> factoryType,@NullableClassLoader classLoader){ClassLoader classLoaderToUse = classLoader;if(classLoaderToUse ==null){
classLoaderToUse =SpringFactoriesLoader.class.getClassLoader();}String factoryTypeName = factoryType.getName();returnloadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName,Collections.emptyList());}privatestaticMap<String,List<String>>loadSpringFactories(ClassLoader classLoader){Map<String,List<String>> result = cache.get(classLoader);if(result !=null){return result;}
result =newHashMap<>();try{Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);while(urls.hasMoreElements()){URL url = urls.nextElement();UrlResource resource =newUrlResource(url);Properties properties =PropertiesLoaderUtils.loadProperties(resource);for(Map.Entry<?,?> entry : properties.entrySet()){String factoryTypeName =((String) entry.getKey()).trim();String[] factoryImplementationNames =StringUtils.commaDelimitedListToStringArray((String) entry.getValue());for(String factoryImplementationName : factoryImplementationNames){
result.computeIfAbsent(factoryTypeName, key ->newArrayList<>()).add(factoryImplementationName.trim());}}}// Replace all lists with unmodifiable lists containing unique elements
result.replaceAll((factoryType, implementations)-> implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(),Collections::unmodifiableList)));
cache.put(classLoader, result);}catch(IOException ex){thrownewIllegalArgumentException("Unable to load factories from location ["+FACTORIES_RESOURCE_LOCATION+"]", ex);}return result;}
@AutoConfigurationPackage注解类
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Import(AutoConfigurationPackages.Registrar.class)/**
用于确定哪些包应被视为 Spring Boot 的自动配置包。这是基于给定的包和父包进行的。其主要用途是在 Spring Boot 的自动配置过程中确定哪些组件或特性应该被考虑和应用。
默认情况下,basePackages的路径就是启动类所在的包路径
会自动扫描项目中那些是自动配置类,然后进行加载
*/public@interfaceAutoConfigurationPackage{/**
* 同下
*/String[]basePackages()default{};/**
* 指定SpringBoot自动配置类应该扫描那些包
*/Class<?>[]basePackageClasses()default{};}