1, an overview of the

Any SpringBoot project will use the launch class, and as you can see from the code below, the Annotation definition (@SpringBootApplication) and the class definition (springApplication.run ()) are the most critical.Copy the code
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}Copy the code

2. @ EnableAutoConfiguration

@SpringBootApplication
Copy the code
@Configuration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
Copy the code

Note: For SpringBoot, @SpringBootApplication is the set of @Configuration, @EnableAutoConfiguration and @ComponentScan. Therefore, granularity management of @enableAutoConfiguration also exists.

1. @SpringBootConfiguration inherits from @Configuration and has the same functionality. It marks the current class as a Configuration class and adds one or more instances of methods declared in the current class marked by the @Bean annotation to the Spring container.

Used to load the Spring container for beans

@enableAutoConfiguration enables automatic configuration. The @enableAutoConfiguration annotation means that Springboot configures the default configuration of your project based on the jar package you added. For example, using spring-boot-starter-Web to determine whether your project needs to add WebMVC and Tomcat will automatically configure the default configuration for your Web project. The blog will examine this comment in detail below.

Used to configure add JAR package default configuration items

3. @ComponentScan: scans the current package and its subpackages for classes marked by @Component, @Controller, @Service, and @Repository and adds them to the Spring container for management. Is old (used to use tags used in XML to scan parallel support for package configuration).

Core configuration for adding the Spring container

Note:

The above separate configuration replaces SpringBootApplication, which is recommended for development efficiency.

  • So let’s go through each of these annotations.

@Configuration

@Configuration is the same @Configuration that is used in the Configuration class of the Spring Ioc container in JavaConfig form. The SpringBoot community recommends using the Javaconfig-based Configuration form. The startup class labeled @Configuration is itself a Configuration class for the IoC container.

The @ComponentScan annotation is very important in Spring. It corresponds to elements in the XML configuration. The @ComponentScan annotation automatically scans and loads qualified components (@Component, @Repository, etc.) or bean definitions. These bean definitions are eventually loaded into the IoC container.

We can fine-grained customize the scope that @ComponentScan automatically scans through properties like basePackages. If not specified, the default Spring framework implementation scans from the package of the class in which @ComponentScan is declared.

Note: So it is best to place the boot class of SpringBoot under the root package, since basePackages are not specified by default.

@EnableAutoConfiguration is an Annotation that I personally feel is the most important, so I put it at the end, Do you remember the various Annotation definitions that the Spring framework provides that start with @enable? For example, @Enablescheduling, @Enablecaching, @enablembeanexport, etc. The concept of @EnableAutoConfiguration is in fact consistent with the way of doing things. A brief summary is that with the support of @import, Collect and register bean definitions associated with specific scenarios.

  • @enablescheduling loads Spring scheduling-framework related bean definitions into the IoC container via @import.
  • @enablembeanExport loads jMX-related bean definitions into the IoC container via @import.

@enableAutoConfiguration loads all auto-configured bean definitions into the IoC container with the help of @import, and that’s it!

As a composite Annotation, @enableAutoConfiguration defines the key information as follows:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<? >[] exclude() default {}; String[] excludeName() default {}; }Copy the code

One of the most critical is @ Import (EnableAutoConfigurationImportSelector. Class), with the aid of EnableAutoConfigurationImportSelector, @enableAutoConfiguration helps SpringBoot applications load all eligible @Configuration configurations into the IoC container currently created and used by SpringBoot. With the support of SpringFactoriesLoader, @enableAutoConfiguration can be automatically configured.Automatic configuration: SpringFactoriesLoader

The SpringFactoriesLoader is a proprietary extension of the Spring framework that loads configurations from a specified configuration file, meta-INF/Spring.Factories.

Used in conjunction with @enableAutoConfiguration, it provides more of a configuration lookup feature, According to the full name of the class of the @ EnableAutoConfiguration org. Springframework. Boot. Autoconfigure. EnableAutoConfiguration as a lookup Key, obtain corresponding to a set of @ Configura Tion class

public final class SpringFactoriesLoader { public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {} public static List<String> loadFactoryNames(Class<? > factoryType, @Nullable ClassLoader classLoader) {}Copy the code

Used in conjunction with @enableAutoConfiguration, it provides more of a configuration lookup feature, According to the full name of the class of the @ EnableAutoConfiguration org. Springframework. Boot. Autoconfigure. EnableAutoConfiguration as a lookup Key, obtain corresponding to a set of @ Configura Tion classes.

An excerpt from the meta-INF/Spring.Factories configuration file in SpringBoot’s autoconfigure dependency package is a good illustration.

So the @enableAutoConfiguration magic knight becomes: Search all meta-INF/Spring. factories configuration files from the classpath, And will the org. Springframework. Boot. Autoconfigure. EnableutoConfiguration corresponding configuration items through reflection (Java Refletion) instantiated into the corresponding IoC container Configuration class in JavaConfig form annotated with @Configuration, then aggregated into one and loaded into the IoC container.

3. SpringApplication executes the process

public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
   configureHeadlessProperty();
   SpringApplicationRunListeners listeners = getRunListeners(args); //2
   listeners.starting();
   try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); //3
      configureIgnoreBeanInfo(environment);
      Banner printedBanner = printBanner(environment);
      context = createApplicationContext();
      exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
            new Class[] { ConfigurableApplicationContext.class }, context);
      prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      refreshContext(context);
      afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
      }
      listeners.started(context);
      callRunners(context, applicationArguments);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, listeners);
      throw new IllegalStateException(ex);
   }

   try {
      listeners.running(context);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, null);
      throw new IllegalStateException(ex);
   }
   return context;
}
Copy the code

The implementation of The Run method of SpringApplication is the main route of our journey, and the main process of this method can be summarized as follows:

1) If we use the static run method of SpringApplication, the method will first create an instance of the SpringApplication object, and then call the instance method. When a SpringApplication instance is initialized, it does several things ahead of time:

  • According to the characters of the classpath inside whether there is a certain class (org. Springframework. Web. Context. ConfigurableWebApplicationContext) to decide whether it should be to create a web Application using the Application The Context type.
  • Using SpringFactoriesLoader to look for in the application of the classpath and load all available ApplicationContextInitializer.
  • Use the SpringFactoriesLoader to find and load all available ApplicationListeners in your application’s classpath.
  • Infer and set the definition class for the main method.

2) After the SpringApplication instance is initialized and set, the logic of the run method is executed. First traversal perform all through SpringFactoriesLoader SpringApplicationRunListener can find and load. Call them started () method, tell these SpringApplicationRunListener, “hey, SpringBoot application to start cough up!” .

3) Create and configure the Environment to be used by the current Spring Boot application (including PropertySource and Profile to be used).

4) iterates through all SpringApplicationRunListener call environmentPrepared () method, told them: “the current SpringBoot applications use the Environment ready!” .

5) If the SpringApplication showBanner property is set to true, the banner is printed.

6) Determine what type of ApplicationContext should be created for the current SpringBoot application based on whether the applicationContextClass type has been explicitly set by the user and the inferred results of the initialization phase. Then depending on the conditions, decide whether to add ShutdownHook, decide whether to use a custom BeanNameGenerator, decide whether to use a custom ResourceLoader, and of course, most importantly, Set the previously prepared Environment to be used by the created ApplicationContext.

7) After the ApplicationContext is created, The SpringApplication will use the SpringFactoriesLoader again, To find and load the classpath all available ApplicationContextInitializer, And call these ApplicationContextInitializer initialize traversal (applicationContext) method to already created good applicationContext for further processing.

8) iterates through all SpringApplicationRunListener call contextPrepared () method.

9) The most essential step is to load all the configuration obtained via @enableAutoConfiguration and other forms of IoC container configuration into the prepared ApplicationContext.

10) iterates through all SpringApplicationRunListener call contextLoaded () method.

11) Call the Refresh () method of the ApplicationContext to complete the final procedure available to the IoC container.

12) Find if CommandLineRunner is registered in the current ApplicationContext, and if so, iterate through them.

13) under normal circumstances, through implementing SpringApplicationRunListener finished () method, (if the abnormal, the whole process is still calling all SpringApplicationRunListener finished () method, Except in this case, the exception message is passed in as well.)

After removing the event notification point, the whole process is as follows:

4,

At this point, the core components of SpringBoot have completed the basic analysis, in general, most of them are some concepts and practices behind the Spring framework, SpringBoot is only in these concepts and practices for specific scenes in advance of solidification and sublimation, It is this solidification that makes developing applications based on the Sping framework easier and more efficient.