SpringBoot-Operation Principle

1 SpringBoot automatic assembly principle

1.1 pom.xml

parent dependency

Among them, it mainly depends on a parent project, mainly to manage the resource filtering and plug-ins of the project!

		<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

Click in and find that there is also a parent dependency

	<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.6.0</version>
  </parent>

  This is the place to really manage all the dependent versions in the SpringBoot application, the version control center of SpringBoot;

In the future, when we import dependencies, we do not need to write the version by default; but if the imported package is not managed in the dependency, we need to manually configure the version ;

starter spring-boot-starter

<!--web依赖:tomcat,dispatchServlet,xml...-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

springboot-boot-starter-xxx : is the scene starter of spring-boot

spring-boot-starter-web : Helps us import the components that the web module depends on for normal operation;

  SpringBoot extracts all functional scenarios and makes them into starters (starters) one by one. We only need to introduce these starters into the project, and all related dependencies will be imported. We can import what kind of functions we want to use. The scene starter is enough; we can also customize the starter in the future;

1.2 Main startup class

Default main startup class

//@SpringBootApplication 来标注一个主程序类
//说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootApplication {
    
    
   public static void main(String[] args) {
    
    
     //以为是启动了一个方法,没想到启动了一个服务
      SpringApplication.run(SpringbootApplication.class, args);
   }
}

But a simple startup class is not that simple ! Let's analyze what these annotations do

@SpringBootApplication

Function : Mark on a class to indicate that this class is the main configuration class of SpringBoot, and SpringBoot should run the main method of this class to start the SpringBoot application;

Enter this annotation: you can see that there are many other annotations above!

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {
    
    @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    
    
    // ......
}

@ComponentScan

This annotation is very important in Spring, it corresponds to the element in the XML configuration.

Function: Automatically scan and load eligible components or beans, and load this bean definition into the IOC container

@SpringBootConfiguration

Function: The configuration class of SpringBoot, marked on a class, indicates that this is a configuration class of SpringBoot;

Let's continue to go into this annotation to view

// 点进去得到下面的 @Component
@Configuration
public @interface SpringBootConfiguration {
    
    }
@Component
public @interface Configuration {
    
    }

The @Configuration here indicates that this is a configuration class, and the configuration class is the xml configuration file corresponding to Spring;

The @Component in it means that the startup class itself is just a component in Spring, responsible for starting the application!

Let's go back to the SpringBootApplication annotation to continue.

@EnableAutoConfiguration

@EnableAutoConfiguration : Enable automatic configuration

  In the past, we needed to configure things ourselves, but now SpringBoot can automatically configure it for us; @EnableAutoConfiguration tells SpringBoot to turn on the automatic configuration function, so that the automatic configuration can take effect;

Click on the note to continue viewing:

@AutoConfigurationPackage : Automatic configuration package

@Import({
    
    Registrar.class})
public @interface AutoConfigurationPackage {
    
    
}

@import : Spring’s underlying annotation @import , import a component into the container

Registrar.class Function: Scan all components in the package where the main startup class is located and all subpackages under the package to the Spring container;

This analysis is over, go back to the previous step and continue to read

@Import ({AutoConfigurationImportSelector.class}) : import components to the container;

AutoConfigurationImportSelector : Automatically configure the import selector, so which component selectors will it import? We click to go to this class to see the source code:

1. There is a method like this in this class

// 获得候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    
    
    //这里的getSpringFactoriesLoaderFactoryClass()方法
    //返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}

2. This method calls the static method of the SpringFactoriesLoader class! We enter the SpringFactoriesLoader class loadFactoryNames() method

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
    
    
    String factoryClassName = factoryClass.getName();
    //这里它又调用了 loadSpringFactories 方法
    return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}

3. We continue to click to view the loadSpringFactories method

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    
    
    //获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身
    MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
    if (result != null) {
    
    
        return result;
    } else {
    
    
        try {
    
    
            //去获取一个资源 "META-INF/spring.factories"
            Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
            LinkedMultiValueMap result = new LinkedMultiValueMap();
            //将读取到的资源遍历,封装成为一个Properties
            while(urls.hasMoreElements()) {
    
    
                URL url = (URL)urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                Iterator var6 = properties.entrySet().iterator();
                while(var6.hasNext()) {
    
    
                    Entry<?, ?> entry = (Entry)var6.next();
                    String factoryClassName = ((String)entry.getKey()).trim();
                    String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                    int var10 = var9.length;
                    for(int var11 = 0; var11 < var10; ++var11) {
    
    
                        String factoryName = var9[var11];
                        result.add(factoryClassName, factoryName.trim());
                    }
                }
            }
            cache.put(classLoader, result);
            return result;
        } catch (IOException var13) {
    
    
            throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
        }
    }
}

4. Find a file that appears multiple times: spring.factories, search for it globally

spring.factories

  We opened spring.factories based on the source and saw a lot of auto-configured files; this is where the auto-configuration source lies!

img

WebMvcAutoConfiguration

  Let's find one of the above automatic configuration classes to open it, for example: WebMvcAutoConfiguration

img

  You can see that these are all JavaConfig configuration classes, and they all have some beans injected. You can find some classes you know and look familiar!

  Therefore, the real implementation of automatic configuration is to search all META-INF/spring.factories configuration files from the classpath, and instantiate the configuration items under the corresponding org.springframework.boot.autoconfigure. package to the corresponding annotations through reflection. The IOC container configuration class in the form of @Configuration's JavaConfig is then aggregated into an instance and loaded into the IOC container.

Conclusion :

1. SpringBoot obtains the value specified by EnableAutoConfiguration from META-INF/spring.factories in the classpath at startup

2. Import these values ​​into the container as automatic configuration classes, and the automatic configuration classes will take effect, helping us with automatic configuration work;

3. The overall solution and automatic configuration of the entire J2EE are in the jar package of springboot-autoconfigure;

4. It will import a lot of automatic configuration classes (xxxAutoConfiguration) into the container, that is, import all the components required for this scene into the container, and configure these components;

5. With the automatic configuration class, we save the work of manually writing configuration injection function components;

2 SpringApplication

not easy way

At first I thought it was running a main method, but I didn't expect to start a service;

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

Analysis of SpringApplication.run

  The analysis method is mainly divided into two parts, one is the instantiation of SpringApplication, and the other is the execution of the run method;

SpringApplication

This class mainly does the following four things :

1. Infer whether the type of application is a normal project or a web project

2. Find and load all available initializers and set them to the initializers property

3. Find all application listeners and set them to the listeners property

4. Infer and set the definition class of the main method to find the running main class

Check out the constructor:

public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
    
    
    // ......
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.setInitializers(this.getSpringFactoriesInstances();
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}

run method process analysis

img

Analysis of SpringBoot automatic assembly principle

https://www.kuangstudy.com/bbs/1354249887209791489

img

Conclusion: All the automatic configurations of springboot are scanned and loaded at startup: all the automatic configuration classes of spring.factories are here, but they may not take effect. To judge whether the conditions are true, as long as the corresponding start is imported, there will be corresponding The launcher, with the launcher, our automatic assembly will take effect, and then the configuration is successful!

1. When springboot starts, it obtains the specified value from /META-INF/spring.factories in the classpath;

⒉ Import these auto-configured classes into the container, and the auto-configuration will take effect. Help me with the auto-configuration!

3. Before we needed to configure things automatically, now springboot does it for us!

4. Integrate javaEE, solutions and automatic configuration things are in the package spring-boot-autoconfigure-2.2.0.RELEASE.jar

5. It will return all the components that need to be imported in the form of class names, and these components will be added to the container;

6. There will also be a lot of xAutoConfiguration files ( @Bean ) in the container, and it is these classes that import all the components needed for this scene into the container; and automatically configure, @Configuration , JavaConfig!

7. With the automatic configuration class, we save the work of manually writing configuration files! |

Guess you like

Origin blog.csdn.net/qq_41355222/article/details/123959813