Dwell @SpringBootApplication comment springboot start classes

A few days ago we learned how to create a project springboot Today we talk about how he runs Why we do not need to go write heavy profiles

@SpringBootApplication

First we look at this comment, he is used to mark the main program, that he is a springboot project

@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 {
}

 

After the click-through @SpringBootApplication comment we focus on the last three notes

@ComponentScan (Pack scan)
  • component is a component, scan scan, so the meaning of this annotation is used to scan component,

  • All components need to inject componentScan is to scan the marked classes reside under the package, which is injected, where he is reflected in @SpringBootApplication in, so this comment is automatically injected into the main program where all the components in the package

  • Previously ssm project we need to configure our packages scan

  
<context:component-scan base-package="com.xxx"></context:component-scan>

 

@EnableAutoConfiguration (automatic assembly Open)
@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 {};
  }

Here we focus on two notes

一、@AutoConfigurationPackage

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

 

In this annotation, primarily to obtain components under our own package to comment register

  
 static  class Registrar the implements ImportBeanDefinitionRegistrar, DeterminableImports { 
          Registrar () { 
          } 
    // Metadata annotation is located meta information of our 
          public  void registerBeanDefinitions (AnnotationMetadata Metadata, the BeanDefinitionRegistry Registry) {
             // see where all the components of our own package to be annotated Register 
              AutoConfigurationPackages.register (Registry, ( new new AutoConfigurationPackages.PackageImport (Metadata)) getPackageName ().); 
          } 
          public the Set <Object> determineImports (AnnotationMetadata Metadata) {
               return Collections.singleton(new AutoConfigurationPackages.PackageImport(metadata));
          }
      }

 

register method: AutoConfigurationPackages registered by the component to the package

  
 Private  static  Final String BEAN = AutoConfigurationPackages. class .getName (); 
  public  static  void Register (the BeanDefinitionRegistry Registry, packagenames String ...) {
      // first determine the whole has not been registered BEAN 
          IF (registry.containsBeanDefinition (BEAN)) {
             // Get the bean define 
              the BeanDefinition BeanDefinition = registry.getBeanDefinition (bEAN);
             // Get the value of the parameter by the constructor bean 
              ConstructorArgumentValues constructor Arguments = beanDefinition.getConstructorArgumentValues ();
             // add the parameter values,
              constructorArguments.addIndexedArgumentValue (0 , addBasePackages (Constructor Arguments, packagenames)); 
          } the else {
             // create a new definition of the bean 
              GenericBeanDefinition BeanDefinition = new new GenericBeanDefinition ();
             // set the type of the bean is AutoConfigurationPackages type 
              beanDefinition.setBeanClass (AutoConfigurationPackages.BasePackages . class ); 
              beanDefinition.getConstructorArgumentValues () addIndexedArgumentValue (. 0 , packagenames); 
              beanDefinition.setRole ( 2 );
             // for registration bean
              registry.registerBeanDefinition(BEAN, beanDefinition);
          }
      }

 

二、@Import({AutoConfigurationImportSelector.class})

Our automatic assembly configuration into selector

We point into this class, there is a following method getAutoConfigurationEntry acquired automatic assembly inlet,

  
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
          if (!this.isEnabled(annotationMetadata)) {
              return EMPTY_ENTRY;
          } else {
              AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
              List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
              configurations = this.removeDuplicates(configurations);
              Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
              this.checkExcludedClasses(configurations, exclusions);
              configurations.removeAll(exclusions);
              configurations = this.filter(configurations, autoConfigurationMetadata);
              this.fireAutoConfigurationImportEvents(configurations, exclusions);
              return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
          }
      }

 

This way he mainly gained configurations of a collection at this point we go getCandidateConfigurations method

  
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
          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;
      }

 

We first see him this red error message: META-INF / spring.factories not found automatically configure class. According to his error message we can conclude that he is to get our automatic configuration information from the META-INF / spring.factories

We can also enter at this point loadFactoryNames this method

   public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
          String factoryClassName = factoryClass.getName();
     //调用了下面的方法loadSpringFactories
          return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
      }
  ​
      private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
          MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
          if (result != null) {
              return Result; 
          } the else {
               the try {
                 // to obtain the configuration file information according to the class loader to 
                  the Enumeration <the URL> = URLs classLoader =! null ClassLoader.getResources ( "the META-INF / spring.factories"):? ClassLoader.getSystemResources ( "the META-INF / spring.factories" ); 
                  LinkedMultiValueMap Result = new new LinkedMultiValueMap (); 
                  the while (urls.hasMoreElements ()) { 
                      the URL URL = (the URL) urls.nextElement (); 
                      a UrlResource Resource = new newA UrlResource (URL);
                     // configuration information becomes final conversion after many properties form 
                      the Properties properties = PropertiesLoaderUtils.loadProperties (Resource); 
                      the Iterator var6 = properties.entrySet () Iterator ();.
                   // loop configuration information acquired all 
                      the while ( var6.hasNext ()) { 
                          the entry <? ?,> = entry (the 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);
              }
          }
      }

 

And this configuration file where is it

Find our spring-boot-autoconfigure in our project External Libraries

This completes our default equipped with some automatic

@SpringBootConfiguration

This method is relatively simple, indicating that this is a configuration class

  @Target({ElementType.TYPE})
  @Retention(RetentionPolicy.RUNTIME)
  @Documented
  @Configuration
  public @interface SpringBootConfiguration {
  }
 
The three of us to comment on this finished, bigwigs have any questions, please specify Thank you.

There have been struggles, there have been failures, but will still get up and continue fighting

 

Guess you like

Origin www.cnblogs.com/guomie/p/11241306.html