SpringBoot 源码调试

SpringBoot 源码调试

SpringApplication 的构造方法

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		this.bootstrapRegistryInitializers = new ArrayList<>(
				getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

getSpringFactoriesInstances

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
		ClassLoader classLoader = getClassLoader();
		// Use names and ensure unique to protect against duplicates	使用名称并确保唯一,以防止重复
		Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
  	// 创建springFactories 的实例
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
		AnnotationAwareOrderComparator.sort(instances);
		return instances;
	}

loadSpringFactories

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
		ClassLoader classLoaderToUse = classLoader;
		if (classLoaderToUse == null) {
			classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
		}
		String factoryTypeName = factoryType.getName();
		return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
	}

主要是 private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader)这个方法

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

		result = new HashMap<>();
		try {
			Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(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 -> new ArrayList<>())
								.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) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
		return result;
	}

通过 loadProperties(resource) 加载 spring.factories 这个文件

加载配置文件

会去加载 file:/opt/maven/repo/org/springframework/boot/spring-boot/2.6.2/spring-boot-2.6.2.jar!/META-INF/spring.factories 这个文件

image-20220109190859845

以一个 Map<String, List<String>> 的形式,存到result中:

image-20220109191131973

factoryTypeName="org.springframework.boot.BootstrapRegistryInitializer"
loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());  

此时返回一个空集合

开始创建 SpringFactories 的实例,并返回

image-20220109191432404

接下来 设置初始化器到实例,设置监听器到实例,然后开始执行 run()方法

image-20220109191709381

run()

public ConfigurableApplicationContext run(String... args) {
  	// 设置启动时间
		long startTime = System.nanoTime();
  	// 创建一个bootstrapContext  一个bootstrapContext
		DefaultBootstrapContext bootstrapContext = createBootstrapContext();
		ConfigurableApplicationContext context = null;
  	// 配置HeadlessProprty(不知道干嘛的)
		configureHeadlessProperty();
  	// 获取运行时 spring监听器
		SpringApplicationRunListeners listeners = getRunListeners(args);
  	// 启动这个监听器
		listeners.starting(bootstrapContext, this.mainApplicationClass);
		try {
      // 创建了一个啥玩意儿
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      // 将上面的参数传进去,获取一个 Environment 对象
			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
      // 配置了一些什么东西 不知道
			configureIgnoreBeanInfo(environment);
      // 打映Banner 就是 spring
			Banner printedBanner = printBanner(environment);
      // 创建 鹅不啦剋婶康泰克死
			context = createApplicationContext();
      // 给 applicatonContext 设置属性
			context.setApplicationStartup(this.applicationStartup);
			// 准备这个 context ! 识别到启动类,判断启动类是不是一个 可配置类
			prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
      // 终于 refresh 这个 context 了
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
			}
			listeners.started(context, timeTakenToStartup);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, listeners);
			throw new IllegalStateException(ex);
		}
		try {
			Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
			listeners.ready(context, timeTakenToReady);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

prepareEnvironment

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
			DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
		// Create and configure the environment
		ConfigurableEnvironment environment = getOrCreateEnvironment();
		configureEnvironment(environment, applicationArguments.getSourceArgs());
		ConfigurationPropertySources.attach(environment);
		listeners.environmentPrepared(bootstrapContext, environment);
		DefaultPropertiesPropertySource.moveToEnd(environment);
		Assert.state(!environment.containsProperty("spring.main.environment-prefix"),
				"Environment prefix cannot be set via properties.");
		bindToSpringApplication(environment);
		if (!this.isCustomEnvironment) {
			environment = convertEnvironment(environment);
		}
		ConfigurationPropertySources.attach(environment);
		return environment;
	}

整个就是获取一个 Environment 对象,并且初始化

configureIgnoreBeanInfo

private void configureIgnoreBeanInfo(ConfigurableEnvironment environment) {
		if (System.getProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME) == null) {
			Boolean ignore = environment.getProperty("spring.beaninfo.ignore", Boolean.class, Boolean.TRUE);
			System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME, ignore.toString());
		}
	}

设置属性,不懂....

posted @ 2022-01-10 10:06  jalivv  阅读(281)  评论(0)    收藏  举报