SpringBoot process analysis (1)

Table of contents

annotation

SpringApplication::SpringApplication

one

two

three

four

Wu

land


I haven't watched SpringBoot for a long time, so I'll review it and learn from the past.

@SpringBootApplication
public class SecurityApplication {
    public static void main(String[] args) {
        SpringApplication.run(SecurityApplication.class,args);
    }
}

annotation

The vernacular teaches you how to perform automatic configuration in @SpringBootApplication /details/122049950?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166157703016782390538284%2522%252C%2522scm%2522%253A%2522201407 13.130102334.pc%255Fblog.%2522%257D&request_id=166157703016782390538284&biz_id=0&utm_medium=distribute.pc_search_result.none -task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-122049950-null-null.nonecase&utm_term=springboot&spm=1018.2226.3001.4450 Simply put:

  • The declaration is a spring application configuration class
  • Load this class into the ioc container to complete package scanning
  • Import configuration class
  • According to the defined scanning path, assemble the classes that meet the scanning rules into the spring container

SpringApplication::SpringApplication

Except for the annotation, there is only one line of code

SpringApplication.run(SecurityApplication.class,args);

 Let's analyze the run method, click in and see

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return (new SpringApplication(primarySources)).run(args);
    }

Let's analyze first

(new SpringApplication(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));
        // 叁
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
        // 肆
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
        // 伍
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        // 陆
		this.mainApplicationClass = deduceMainApplicationClass();
	}

one

Configure resourceLoader

two

Configure the main startup class

three

Determine the type of the current application.

static WebApplicationType deduceFromClasspath() {
		if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
				&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
			return WebApplicationType.REACTIVE;
		}
		for (String className : SERVLET_INDICATOR_CLASSES) {
			if (!ClassUtils.isPresent(className, null)) {
				return WebApplicationType.NONE;
			}
		}
		return WebApplicationType.SERVLET;
	}

Determine the application type (reflection) based on whether the Class exists .

four

Get the instance object of the initializer

(Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)

Click inside the code, go to

loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());

 Step 1: Let's look at loadSpringFactories(classLoader)

 Mainly get the classes that need to be loaded from META-INF/spring.factories (deduplication), and finally put them in the cache

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

		try {
			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 factoryTypeName = ((String) entry.getKey()).trim();
					for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
						result.add(factoryTypeName, factoryImplementationName.trim());
					}
				}
			}
			cache.put(classLoader, result);
			return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}

 In the second step, let's look at getOrDefault(factoryTypeName, Collections.emptyList()) :

Take the key out of the map as the value of ApplicationContextInitializer.

Wu

Get the instance object of the listener

The analysis process is the same as above

land

Find the main class of the current application and start executing

Guess you like

Origin blog.csdn.net/wai_58934/article/details/126557165