springboot 加载 META-INF/spring.factories

用户应用程序Application

ConfigurableApplicationContext context = SpringApplication.run(NacosSpringBootYamlApplication.class, args);

 

SpringApplication类

public static ConfigurableApplicationContext run(Class primarySource, String... args) {
		return run(new Class[] { primarySource }, args);
	}

 


// 这里Class是数组
public static ConfigurableApplicationContext run(Class[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}

 


public SpringApplication(Class... primarySources) {
		this(null, primarySources);
	}

 


public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); // 这里就是SpringMvcApplication的实例
		this.webApplicationType = WebApplicationType.deduceFromClasspath();// deduce(推断)web类型(servlet、reactive、NoWeb)
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 这里会处理加载所有的spring.factories文件的内容到缓存 找到*META-INF/spring.factories*中声明的所有ApplicationContextInitializer的实现类并将其实例化
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); //找到*META-INF/spring.factories*中声明的所有ApplicationListener的实现类并将其实例化
		this.mainApplicationClass = deduceMainApplicationClass(); //获得当前执行main方法的类对象,这里就是SpringMvcApplication的实例
	}

 

 

具体加载该classLoader下的所有spring.factories到缓存 

如果缓存已经存在,则直接根据key,返回数据

/** key:是spring.factories的key    value:是根据key分组,把同个key的不同value放到list里面 */
	private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {
		MultiValueMap result = cache.get(classLoader);
		if (result != null) { //已经处理过了  直接返回
			return result;
		}
//url: // file:/C:/Users/kongqi/.m2/repository/org/springframework/spring-beans/5.1.9.RELEASE/spring-beans-5.1.9.RELEASE.jar!/META-INF/spring.factories
		try { //得到classloader下的所有jar包中的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); // 得到spring.factories的内容
				for (Map.Entry entry : properties.entrySet()) { // key: spring.factories的key  value: spring.factories的value
					String factoryClassName = ((String) entry.getKey()).trim(); // spring.factories的key
					for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {//value根据逗号,分隔
						result.add(factoryClassName, factoryName.trim()); //factoryClassName其实就是spring.factories的key   由于value是List类型 MultiValueMap value有多个
					}
				}
			}
			cache.put(classLoader, result);
			return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}

 

流程图

springboot 加载 META-INF/spring.factories_第1张图片

 

 

 

 

 

 

 

 

你可能感兴趣的:(springsource,springboot)