SpringBoot (anotación)

1. Analiza las principales anotaciones de clase

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = "com.wangxing.springboot")
public class Springbootdemo1Application {
    
    
    public static void main(String[] args) {
    
    
  	SpringApplication.run(Springbootdemo1Application.class, args);
    }
}

@SpringBootApplication
código fuente:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
    
     @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    
    
........
}

1. @SpringBootApplication es en realidad una anotación compuesta.
Aunque su definición usa múltiples anotaciones, de hecho, para las aplicaciones SpringBoot, solo hay tres anotaciones importantes, estas tres anotaciones:

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

Por lo tanto, si usamos las tres anotaciones anteriores en la clase principal, toda la aplicación SpringBoot aún puede ser funcionalmente equivalente a la clase de inicio anterior.

package com.wangxing.springboot.springbootdemo2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurationExcludeFilter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
    
     @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public class Springbootdemo2Application {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(Springbootdemo2Application.class, args);
    }
}

Pero escribir tres anotaciones cada vez es obviamente demasiado engorroso, por lo que obviamente es más conveniente escribir una anotación compuesta única como @SpringBootApplication.
Anotación @SpringBootConfiguration [crear clase de configuración para reemplazar el archivo de configuración]
La anotación @SpringBootConfiguration incluye @Configuration.
@Configuration: es la anotación utilizada por la clase de configuración del contenedor Spring IoC en forma de Spring JavaConfig. Dado que la aplicación SpringBoot es una aplicación Spring en su núcleo, es naturalmente necesario cargar la configuración de un determinado contenedor de IoC, y la comunidad SpringBoot recomienda el uso de un formulario de configuración basado en JavaConfig. Por lo tanto, es obvio que la clase de inicio aquí está anotado con @Configuration. También es una clase de configuración para un contenedor de IoC. Método
de
configuración del contenedor Spring IoC en forma de Spring JavaConfig
1. Método de configuración basado en XML.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
<!-- bean定义 -->

</beans>

2. Método de configuración basado en JavaConfig

@Configuration
public class MyConfiguration{
// bean定义
} 

Cualquier definición de clase Java marcada con @Configuration es una clase de configuración JavaConfig.
Definición de bean de registro
1. Método de definición de bean de registro basado en XML.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
<!-- bean定义 -->
<bean id=””  class=””></bean>
</beans>

2. El método de definición de bean registrado basado en JavaConfig.

@Configuration
public class MyConfiguration{
    
    
// bean定义
 	@Bean
    public StudentService  studentService() {
    
    
        return new StudentServiceImpl();
    }
} 

Para cualquier método anotado con @Bean, su valor de retorno se registrará como una definición de bean en el contenedor IoC de Spring, y el nombre del método será el id de la definición de bean por defecto.
Método
de configuración de inyección de dependencia 1. Método de inyección de dependencia basado en XML

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
<!-- bean定义 -->
<bean id=””  class=””>
<property name="studentDao" ref="studentDao" />
</bean>
</beans>

2. Método de inyección de dependencia basado en JavaConfig.

@Configuration
public class MyConfiguration{
    
    
// bean定义
 	@Bean
    public StudentService  studentService() {
    
    
        return new StudentServiceImpl(studentDao() );
}

	@Bean
    public  StudentDao  studentDao() {
    
    
        return new StudentDaoImpl();
	}
} 

Si la definición de un bean depende de otros beans, simplemente llame al método de creación del bean dependiente en la clase JavaConfig correspondiente directamente.

@SpringBootApplication contiene la anotación @SpringBootConfiguration, la anotación @SpringBootConfiguration contiene la anotación @Configuration, en qué clase java está marcada la anotación @Configuration, entonces esta clase java es una clase de configuración JavaConfig, esta clase de configuración JavaConfig puede reemplazar el archivo de configuración Spring [ApplicationContext.xml ], cuando anotamos @SpringBootApplication en la clase principal, significa que la clase principal es una clase de configuración JavaConfig, por lo que no necesitamos escribir el archivo de configuración Spring [applicationContext.xml] al crear el proyecto SptingBoot.

@EnableAutoConfiguration [configuración automática completa "inteligente"]
1. @EnableAutoConfiguration contiene la anotación
@Import Anotación @Import para registrar el objeto bean en la clase de configuración javaConfig.
@EnableAutoConfiguration anotación utiliza @Import anotación para recoger y registrar las definiciones de frijol relacionados con los módulos específicos.
El código fuente:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
......
}

@Import (AutoConfigurationImportSelector.class). Con la ayuda de EnableAutoConfigurationImportSelector, @EnableAutoConfiguration puede ayudar a las aplicaciones SpringBoot a cargar todas las configuraciones de @Configuration elegibles en el contenedor IoC actual creado y utilizado por SpringBoot.
Inserte la descripción de la imagen aquí

Con el apoyo de una clase de herramienta original del marco Spring: SpringFactoriesLoader, @EnableAutoConfiguration puede configurar automáticamente la función "inteligentemente" para que tenga éxito.

En la clase AutoConfigurationImportSelector.class de ** @ Import (AutoConfigurationImportSelector.class) **

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
         getBeanClassLoader());
   Assert.notEmpty(configurations, "No auto configuration classes found in METAINF/spring.factories. If you "+ "are using a custom packaging, make sure that file is correct.");
   return configurations;
}

SpringFactoriesLoader 类

public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
    
    
   Assert.notNull(factoryType, "'factoryType' must not be null");
   ClassLoader classLoaderToUse = classLoader;
   if (classLoaderToUse == null) {
    
    
      classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
   }
   List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
   if (logger.isTraceEnabled()) {
    
    
      logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
   }
   List<T> result = new ArrayList<>(factoryImplementationNames.size());
   for (String factoryImplementationName : factoryImplementationNames) {
    
    
      result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
   }
   AnnotationAwareOrderComparator.sort(result);
   return result;
}
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) {
    
    
   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;
}


public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
spring-boot-autoconfigure-2.4.0.jar/META-INF/spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
...........

Principio de configuración automática del núcleo de SpringBoot
1). Cuando se inicia SpringBoot, se carga la clase de configuración principal y se activa la función de configuración automática. La
clase principal de @EnableAutoConfiguration agrega la anotación @SpringBootConfiguration, la anotación de @SpringBootConfiguration incluye la anotación de @EnableAutoConfiguration
2). @EnableAutoConfiguration anotación 2). utiliza @Import (el EnableAutoConfigurationImporttSelector parámetro en AutoConfigurationImportSelector.class) importaciones algunos componentes en
la SpringIOC recipiente; encontrar autoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry (annotationMetadata); encontrar el
getAutoConfigurationEntry ( método), configuraciones list = getCandidate configuraciones = getCandidate atributos);
getCandidateConfigurations () para obtener
configuraciones de lista = SpringFactoriesLoader.loadFactoryNames (getSpringFactoriesLoaderFactoryClass (),
getBeanClassLoader ()); Obtenga la clase SpringFactoriesLoader y busque loadSpringFactories () a través del método loadFactoryNames en la clase SpringFactoriesLoader. Hay una oración Properties = PropertiesLoaderUtils.loadProperties (resource);
get public static final String FACTORIES_RESOURCE_LOCATION / = "METODOURCE_LOCATION =" spring. "factories";
Escanea todas las rutas de clase del paquete jar, META-INF / spring.factories empaqueta
el contenido escaneado de estos archivos en objetos de propiedades
para obtener los valores correspondientes a la clase EnableAutoConfiguration.class (nombre de clase) de las propiedades, y luego póngalos Agregar al contenedor, agregue todos los valores de EnableAutoConfiguration configurados en META-INF / spring.factories bajo la ruta de clase al contenedor
3) Cada clase de autoconfiguración realiza la función de autoconfiguración;
4). A juzgar por las diferentes condiciones actuales, ¿decidir si esta clase de configuración entra en vigor? Una vez que la clase de configuración entre en vigencia, esta configuración se agregará al contenedor de clases de varios componentes, estas propiedades del componente se obtienen de las propiedades correspondientes de la clase, cada una de estas clases cuya propiedad es vinculante y perfil.
En HttpEncodingAutoConfiguration (Codificación Http configuración automática) es un ejemplo para explicar el principio de configuración automática;
// Significa que esta es una clase de configuración. No es lo mismo que el archivo de configuración escrito anteriormente, y también se pueden agregar componentes al contenedor.

@Configuration(proxyBeanMethods = false)
//启动指定类的ConfigurationProperties功能,将配置文件中对应的值和HttpEncodingAutoConfigurationProperties绑定起来;
@EnableConfigurationProperties(ServerProperties.class)
//Spring底层@Conditional注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效(即判断当前应用是否是web应用)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码处理的过滤器
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

   private final Encoding properties;

   public HttpEncodingAutoConfiguration(ServerProperties properties) {
      this.properties = properties.getServlet().getEncoding();
   }

   @Bean
   @ConditionalOnMissingBean
   public CharacterEncodingFilter characterEncodingFilter() {
      CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
      filter.setEncoding(this.properties.getCharset().name());
      filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
      filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
      return filter;
   }

   @Bean
   public LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
      return new LocaleCharsetMappingsCustomizer(this.properties);
   }

   static class LocaleCharsetMappingsCustomizer
         implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {

      private final Encoding properties;

      LocaleCharsetMappingsCustomizer(Encoding properties) {
         this.properties = properties;
      }

      @Override
      public void customize(ConfigurableServletWebServerFactory factory) {
         if (this.properties.getMapping() != null) {
            factory.setLocaleCharsetMappings(this.properties.getMapping());
         }
      }

      @Override
      public int getOrder() {
         return 0;
      }
   }
}

5. Todas las propiedades que se pueden configurar en el archivo de configuración están encapsuladas en la clase xxxxPropertites. Lo que se puede configurar en el archivo de configuración puede referirse a la clase de propiedad correspondiente a una determinada función;
@ComponentScan
[Configure el paquete de escaneo automático, usted puede permitir que la clase Las clases java con @Component y @Repository, @Service anotaciones crean objetos]
@ComponentScan corresponde al elemento <context: component-scan> en el formulario de configuración XML, utilizado para cooperar con algunas anotaciones de metainformación, tales como @Component y @Repository, etc., recopile las clases de definición de bean marcadas con estas anotaciones de metainformación en el contenedor IoC de Spring en lotes. Podemos personalizar detalladamente el alcance del escaneo automático de @ComponentScan a través de atributos como paquetes base. Si no se especifica, la implementación del marco de Spring predeterminada escaneará desde el paquete donde se declara la clase @ComponentScan.
Si nuestra aplicación actual no tiene ninguna definición de bean que deba cargarse en el contenedor de IoC utilizado por la aplicación SpringBoot actual a través de @ComponentScan, entonces, eliminando la declaración @ComponentScan, la aplicación SpringBoot actual aún puede ejecutarse como de costumbre con funciones equivalentes.


Inserte la descripción de la imagen aquí
Los archivos META-INF de los componentes clave de la configuración automática de SpringBoot mybatis-spring-boot-starter, spring-boot-starter-web y otros componentes contienen el archivo spring.factories. En el módulo de configuración automática, el nombre completo del clase recopilada en el archivo por SpringFactoriesLoader y Devuelve una matriz del nombre completo de la clase. El nombre completo de la clase devuelta se crea una instancia a través de la reflexión para formar una instancia de fábrica específica. La instancia de fábrica genera los beans que el componente necesita específicamente .

Supongo que te gusta

Origin blog.csdn.net/guoguo0717/article/details/110622303
Recomendado
Clasificación