SpringBoot notas de estudio 2-un estudio preliminar sobre el principio de funcionamiento

copiar notas de las direcciones de artículos originales de dios loco
que escribimos antes de HelloSpringBoot, al final es cómo ejecutarlo, proyecto Maven, que normalmente exploramos desde el archivo pom.xml;

pom.xml

Dependencia principal
Entre ellos, depende principalmente de un proyecto principal, principalmente gestionando el filtrado de recursos y los complementos del proyecto.

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

Haga clic y descubra que hay otra dependencia de los padres

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

Inserte la descripción de la imagen aquí

Este es el lugar para administrar verdaderamente todas las versiones dependientes en la aplicación SpringBoot, el centro de control de versiones de SpringBoot;

En el futuro, importaremos dependencias por defecto sin escribir la versión, pero si el paquete importado no se administra en la dependencia, es necesario configurar manualmente la versión;

Arrancador primavera-arranque-arrancador


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

springboot-boot-starter-xxx: es el iniciador de escena de spring-boot

spring-boot-starter-web: Ayúdanos a importar los componentes de los que depende el módulo web para su funcionamiento normal;

SpringBoot extrae todos los escenarios funcionales en un iniciador (iniciador), solo es necesario introducir estos iniciadores en el proyecto, se importarán todas las dependencias relacionadas, importaremos qué tipo de función queremos usar El iniciador de escena es suficiente; podemos también personalice el motor de arranque en el futuro; consulte todos los arrancadores en el
sitio web oficial

Clase de salida principal

Después de analizar pom.xml, echemos un vistazo a la clase de inicio principal predeterminada de esta
clase de inicio

//@SpringBootApplication 来标注一个主程序类
//说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootApplication {
    
    

   public static void main(String[] args) {
    
    
     //以为是启动了一个方法,没想到启动了一个服务
      SpringApplication.run(SpringbootApplication.class, args);
   }
}

¡Pero una clase de inicio simple no es simple! Analicemos lo que hacen estas anotaciones. Función
@SpringBootApplication
: Anote una cierta clase para indicar que esta clase es la clase de configuración principal de SpringBoot, y SpringBoot debería ejecutar el método principal de esta clase para iniciar la aplicación SpringBoot;

Ingrese esta nota: ¡puede ver que hay muchas otras notas arriba!


@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(//@CompontentScan 的作用是 扫描配置的包(TypeExcludeFilter,AutoConfigurationExcludeFilter) 并且剔除某些东西
    excludeFilters = {
    
    @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    
    
    // ......
}

@ComponentScan
esta anotación es muy importante en Spring, corresponde al elemento en la configuración XML.

Función: escanea y carga automáticamente componentes calificados o beans, y carga la definición de bean en el contenedor IOC
@SpringBootConfiguration
Función: clase de configuración SpringBoot, marcada en una clase determinada, que indica que se trata de una clase de configuración SpringBoot;

// Haga clic para obtener la siguiente @Configuration
@Configuration // Usado en SpringBootConFiguration, lo que indica que también es una anotación de clase de configuración
pública @interface SpringBootConfiguration {}
- "Haga clic en @Configuration

@Component //说明Configuration 也是spring的组件
 public @interface Configuration {}

La @Configuration aquí significa que esta es una clase de configuración, y la clase de configuración es el archivo de configuración xml correspondiente a Spring;

El @Component dentro significa que la clase de inicio en sí misma es solo un componente en Spring, ¡responsable de iniciar la aplicación!

Volvamos a la anotación SpringBootApplication y sigamos buscando.
# 91A8C7
Continuemos ingresando esta anotación para ver
@EnableAutoConfiguration
@EnableAutoConfiguration: Active la función de configuración automática

En el pasado, necesitábamos configurar las cosas nosotros mismos, pero ahora SpringBoot puede configurarlo automáticamente por nosotros; @EnableAutoConfiguration le dice a SpringBoot que active la función de configuración automática, para que la configuración automática pueda tener efecto;

Notas del punto de conexión a la vista:
@AutoConfigurationPackage: paquete de configuración automática
Inserte la descripción de la imagen aquí
@Target (ElementType.TYPE {})
@Retention (RetentionPolicy.RUNTIME)
@Documented
@ Inherited
Estas son cuatro notas de yuanes, detalles Ver los comentarios y reflexiones de mi blog
@Import ({Registrar .class})
public @interface AutoConfigurationPackage { } @import: anotación inferior de Spring @import, importar un componente al contenedor

Función Registrar.class: Escanea todos los componentes del paquete donde se encuentra la clase de inicio principal y todos los subpaquetes del paquete al contenedor Spring;

Una vez finalizado este análisis, vuelva al paso anterior y continúe leyendo

@EnableAutoConfiguration

@EnableAutoConfiguration: activa la función de configuración automática

En el pasado, necesitábamos configurar las cosas nosotros mismos, pero ahora SpringBoot puede configurarlo automáticamente por nosotros; @EnableAutoConfiguration le dice a SpringBoot que active la función de configuración automática, para que la configuración automática pueda tener efecto;

Haga clic en el comentario para continuar viendo:
Inserte la descripción de la imagen aquí

@AutoConfigurationPackage : paquete de configuración automática

Haga clic en @ AutoConfigurationPackage-》
@Import ({Registrar.class})
public @interface AutoConfigurationPackage { } @import: Spring bottom annotation @import, importe un componente al contenedor

Función Registrar.class: Escanea todos los componentes del paquete donde se encuentra la clase de inicio principal y todos los subpaquetes del paquete al contenedor Spring;

Una vez finalizado este análisis, vuelva al paso anterior y continúe mirando
@Import ({AutoConfigurationImportSelector.class}): Importar componentes al contenedor;

AutoConfigurationImportSelector: configura automáticamente el selector de importación, entonces, ¿qué selectores de componentes importará? Hacemos clic para ir a esta categoría para ver el código fuente:

1. Existe un método de este tipo en esta clase


// 获得候选的配置
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;
}

//上面的方法调用同类下的该方法
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
    
    
        return EnableAutoConfiguration.class;
    }

2. ¡Este método vuelve a llamar al método estático de la clase SpringFactoriesLoader! Ingresamos al método loadFactoryNames () de la clase SpringFactoriesLoader


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

Inserte la descripción de la imagen aquí
2. ¡Este método vuelve a llamar al método estático de la clase SpringFactoriesLoader! Ingresamos al método loadFactoryNames () de la clase SpringFactoriesLoader


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

3. Seguimos haciendo clic para ver el método loadSpringFactories

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. Encontré un archivo que apareció varias veces: spring.factories, búsquelo
globalmente, spring.factories.
Abrimos spring.factories según la fuente y vimos muchos archivos de configuración automática; esta es la fuente de la configuración automática !
Inserte la descripción de la imagen aquí

WebMvcAutoConfiguration

Podemos encontrar uno en la clase de configuración automática anterior para abrirlo, como: WebMvcAutoConfiguration
Inserte la descripción de la imagen aquí

Puede ver que todas estas son clases de configuración de JavaConfig, y se inyectan algunos Beans. ¡Puede encontrar algunas clases que conoce y mirarlas para familiarizarse!

Por lo tanto, la implementación real de la configuración automática es buscar todos los archivos de configuración META-INF / spring.factories desde la ruta de clase y crear una instancia de los elementos de configuración en el paquete org.springframework.boot.autoconfigure. Correspondiente en las anotaciones correspondientes mediante la reflexión. La clase de configuración del contenedor IOC en forma de @Configuration JavaConfig, que luego se agrega a una instancia y se carga en el contenedor IOC.

En conclusión:

Cuando SpringBoot se inicia, obtiene el valor especificado por EnableAutoConfiguration de META-INF / spring.factories en la ruta de clase.

Importe estos valores al contenedor como la clase de autoconfiguración, y la clase de autoconfiguración entrará en vigencia, ayudándonos con el trabajo de autoconfiguración;

Toda la solución general de J2EE y la configuración automática se encuentran en el paquete jar de springboot-autoconfigure;

Importará muchas clases de configuración automática (xxxAutoConfiguration) al contenedor, es decir, importará todos los componentes necesarios para este escenario en el contenedor y configurará estos componentes;

Con la clase de configuración automática, podemos evitar el trabajo de escribir manualmente componentes funcionales de inyección de configuración;

Ahora todos deberían tener una comprensión general del principio operativo de SpringBoot, ¡y lo profundizaremos nuevamente más adelante!

SpringApplication

Springboot clase de inicio principal

package com.zhou.springboot02config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//标注这个类是springboot的应用
@SpringBootApplication
public class Springboot02ConfigApplication {
    
    

    public static void main(String[] args) {
    
    
        //将springboot应用启动
        SpringApplication.run(Springboot02ConfigApplication.class, args);
    }
}

Esta clase hace principalmente las siguientes cuatro cosas:

1. Deduzca si el tipo de aplicación es un proyecto normal o un proyecto web.

2. Busque y cargue todos los inicializadores disponibles y configúrelos en la propiedad de inicializadores

3. Descubra todos los escuchas de la aplicación y configúrelos en la propiedad de escuchas

4. Deduzca y establezca la clase de definición del método principal y busque la clase principal que se ejecuta

Ver el constructor:

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





Ejecutar análisis de proceso de método
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_44788518/article/details/114003513
Recomendado
Clasificación