SpringBoot ~ solve three doubts, why POM No version required for importing dependency in XML file? How does it achieve automatic configuration? How does it start and run?

Why POM You do not need a version to import dependencies in an XML file?

  • SpringBoot is a Maven project in the final analysis. We usually start from POM XML file; In the past, whether it was java web or SSM, we were in POM The import dependency in the XML file needs to implement its version, but there is no version in the SpringBoot project, but it has a parent dependency
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.11.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
  • Click in and find another parent dependency
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.2.11.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
  </parent>
  • We'll find out the secret if we do it again

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

  • In the SpringBoot import dependency, the default is that you do not need to write a version, and it will match the built-in version number by default; However, if the imported package is not managed in the dependency, you need to manually configure the version;

  • In POM There is also one of the most important web initiators in XML

    <dependencies>
        <!--Core dependency, connotation tomcat and dispatchServlet and xml He did all the configuration for us-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
  • Springboot boot starter XXX: the scenario initiator of spring boot

  • Spring boot starter Web: when we create a SpringBoot project and select web dependency, the system helps us import the components that the web launcher depends on for normal operation;

  • SpringBoot extracts all functional scenarios and makes them into starters. You only need to introduce these starters into the project, and all relevant dependencies will be imported. We can import what kind of scenario starters we want to use

How does SpringBoot implement automatic configuration?

  • Let's next look at the main startup class
//Through this annotation, mark that this class is a SpringBoot application
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        //Start SpringBoot
        SpringApplication.run(DemoApplication.class, args);
    }

}
  • It mainly indicates that this is the main startup class through an annotation @ SpringBootApplication, and also indicates that this is a SpringBoot project
  • Enter this annotation: you can see that there are many other annotations above!
@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}
)}
)
  • @ComponentScan
    This annotation is very important in Spring. It corresponds to the elements in the XML configuration. Function: automatically scan and load qualified components or beans, and load the bean definition into the IOC container

  • @SpringBootConfiguration
    Function: the configuration class of SpringBoot is marked on a class to indicate that it is a SpringBoot configuration class;

Let's continue to check this annotation

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}
  • After entering, we found that there is a @ Configuration, which indicates that it is a Configuration class, and the Configuration class is the xml Configuration file corresponding to Spring; That is, this is just a SpringBoot Configuration class. Let's go in again
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";

    boolean proxyBeanMethods() default true;
}
  • The @ Component inside shows that the startup class itself is just a Component in Spring. It is responsible for loading some configuration files when starting the application!

  • Let's go back to the spring boot application annotation and continue.

  • There is a @ EnableAutoConfiguration, as the name suggests, which should be the configuration annotation to realize automatic assembly. @ EnableAutoConfiguration tells SpringBoot to turn on the automatic configuration function, so that the automatic configuration can take effect. Let's click in and have a look

@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 {};
}
  • We found an @ AutoConfigurationPackage: autoconfiguration package. Let's click in
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
  • @Import: Spring's underlying annotation @ import is used to make Spring recognize and import a component into the container

  • Registrar.class function: scan the package of the main startup class and all components in all sub packages under the package to the Spring container

  • This analysis is finished. Step back and continue to look

  • @Import({AutoConfigurationImportSelector.class}): import components to the container. AutoConfigurationImportSelector: automatically configure the import selector. Which component selectors will it import? Let's click this class to see the source code:

  • After entering this class, we have more method names. It is easy to judge what this class is doing. If you want to know more, you can continue to click. However, we will find a very important method getAutoConfigurationEntry. This method is the entry to obtain automatic configuration, and there is a method getCandidateConfigurations to obtain candidate configuration

  • We enter getCandidateConfigurations to get the candidate configurations

  • Let's go into the spring factoriesloader loader

  • We found that a string path spring is used in many loading places Factories, well, if we search this path, we will find the ultimate secret
  • We open spring according to the source I saw a lot of automatic configuration files; This is the root of automatic configuration!
  • We open the configuration webmvcoautoconfiguration of the web we use
@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
    public static final String DEFAULT_PREFIX = "";
    public static final String DEFAULT_SUFFIX = "";
    private static final String[] SERVLET_LOCATIONS = new String[]{"/"};

    public WebMvcAutoConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
    @ConditionalOnProperty(
        prefix = "spring.mvc.hiddenmethod.filter",
        name = {"enabled"},
        matchIfMissing = false
    )
  • You can see that @ Configuration is used at the beginning, which indicates that this is a JavaConfig Configuration class, and all components are injected into Spring using @ Bean
  • At this time, we will find that this seems to be the case. The real implementation of automatic Configuration is to search all meta-inf / spring from the classpath Factories Configuration file, and the corresponding org. Org springframework. boot. autoconfigure. The Configuration items under the package are instantiated into the Configuration class in the form of JavaConfig marked with @ Configuration through reflection, and then these are summarized into an instance and loaded into the IOC container in the form of Bean.
  • What if we click on the configuration class that we did not import the initiator
  • This configuration file will not take effect, because the class required by its internal annotation cannot be found. We can also think like this, spring All configuration classes in the factories file will not be implemented, and will take effect only after importing the corresponding initiator

Conclusion:

All automatic configurations of SpringBoot are scanned and loaded at startup, meta-inf / spring All contents in factories, but not all automatic configuration classes are effective. There will be a judgment condition inside. The judgment condition is whether the start initiator corresponding to this configuration is imported. If so, automatic configuration will be carried out only with the initiator

  1. When SpringBoot starts, get the specified value from / meta-inf / spring factories in the classpath
  2. Import these automatically configured classes into the container, and the automatically configured classes will take effect to help us with automatic configuration
  3. The things we used to configure are all made by springBoot
  4. All solutions and automatic configuration that integrate the whole Java EE are in spring autoconfigure-2.2.11. RELEASE. Jar under this package
  5. He will return all the components to be imported in the form of a class name, and these components will be added to the container
  6. There will be many xxxautoconfiguration files (@ Bean) in the container. It is these classes that import the components required by a scene into the container and automatically configure @ configuration
  7. With automatic configuration, we can save the trouble of automatic configuration

How does it start and run?

  • SpringApplication.run analysis
  • When we enter the run method in the SpringApplication class, we will find that it 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 in the initializers property

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

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

Tags: Java Maven Spring Spring Boot

Posted by ThunderAI on Sun, 08 May 2022 07:00:13 +0300