springboot-introduce.md

springboot-introduce.md

Introduction to springboot

before springboot

  1. To integrate a spring framework, a series of display configurations such as transaction management, MVC, and Thymeleaf-based WEB views are required to integrate a spring framework. The configuration of servlets and filters (such as Spring's DispatcherServlet) also needs to be initialized in web.xml or Servlet. Explicit configuration in the code

  2. Project dependency management is also thankless. Deciding which libraries to use in the project is already a headache. You also need to know which version of these libraries will not conflict with other libraries. This problem is really tricky.

Regardless of the business code, these are indispensable. The emergence of springboot makes it easy

springboot essentials

  1. Start dependent, tell springboot what functions are needed, and he can introduce the needed libraries
  2. Automatic configuration, for many common application functions of spring applications, springboot can automatically provide related configurations
  3. Command line interface (springboot CGI), rarely used
  4. Actuator, which provides the ability to view the internal situation of the application at runtime, is rarely used

Start-up dependency analysis

Springboot reduces the complexity of project dependencies by providing many start-up dependencies. The start-up dependency is essentially a Maven project object dependency, which defines transitive dependencies on other libraries, such as the commonly used dependencies of springboot:

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

You can view the dependency tree through mvn dependency:tree

- org.springframework.boot:spring-boot-starter-web:jar:2.1.2.RELEASE:compile
   +- org.springframework.boot:spring-boot-starter:jar:2.1.2.RELEASE:compile
   |  +- org.springframework.boot:spring-boot:jar:2.1.2.RELEASE:compile
   |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.2.RELEASE:compile
   |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.1.2.RELEASE:compile
   |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:compile
   |  |  |  +- ch.qos.logback:logback-core:jar:1.2.3:compile
   |  |  |/- org.slf4j:slf4j-api:jar:1.7.25:compile
   |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.11.1:compile
   |  |  |/- org.apache.logging.log4j:log4j-api:jar:2.11.1:compile
   |  |/- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
   |  +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
   |  +- org.springframework:spring-core:jar:5.1.4.RELEASE:compile
   |  |/- org.springframework:spring-jcl:jar:5.1.4.RELEASE:compile
   |/- org.yaml:snakeyaml:jar:1.23:runtime
   +- org.springframework.boot:spring-boot-starter-json:jar:2.1.2.RELEASE:compile
   |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.8:compile
   |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
   |  |/- com.fasterxml.jackson.core:jackson-core:jar:2.9.8:compile
   |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.8:compile
   |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.8:compile
   |/- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.8:compile
   +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.2.RELEASE:compile
   |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.14:compile
   |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.14:compile
   |/- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.14:compile
   +- org.hibernate.validator:hibernate-validator:jar:6.0.14.Final:compile
   |  +- javax.validation:validation-api:jar:2.0.1.Final:compile
   |  +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
   |/- com.fasterxml:classmate:jar:1.4.0:compile
   +- org.springframework:spring-web:jar:5.1.4.RELEASE:compile
   |/- org.springframework:spring-beans:jar:5.1.4.RELEASE:compile
 /- org.springframework:spring-webmvc:jar:5.1.4.RELEASE:compile
      +- org.springframework:spring-aop:jar:5.1.4.RELEASE:compile
      +- org.springframework:spring-context:jar:5.1.4.RELEASE:compile
    /- org.springframework:spring-expression:jar:5.1.4.RELEASE:compile

 

Exclude a certain item in the initial dependency and add it directly to the exclusions tag

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
    </exclusions>
</dependency>
 

You can also use other versions instead of the version in the initial dependencies. MAVEN will always use the most recent dependency. This dependency added in the project s build instructions will overwrite another dependency introduced by the transitive dependency.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.3</version>
</dependency>
 

Automatic configuration analysis

Condition

  1. Implement the Condition interface and implement its abstract methods
    //true false 
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
     
  2. Determine whether it is valid in the declaration configuration, as follows to determine whether it is loaded as a Bean code snippet
    @Bean
    //matches true bean
    @Conditional({PetCondition.class})
    public Dog dog(){
        return new Dog();
    }
     

Class Condition annotation

They have similar functions to Condition, which can be regarded as an extension of Condition, which will take effect when the conditions are met.

  • @ConditionalOnBean-a specific bean is configured
  • @ConditionalOnMissingBean-no specific bean is configured
  • @ConditionalOnClass-there is a specified class in the Classpath
  • @ConditionalOnMissingClass-The specified class is missing from the Classpath
  • @ConditionalOnExpression The calculation result of the given SpEL expression is true
  • @ConditionalOnJava The version of java matches a specific value or a range of values
  • @ConditionalOnJndi The JNDI location given in the parameter must exist one, if there is no parameter, the JNDI InitialContext is required
  • @ConditionalOnProperty Specify that the configuration property must have a clear value
  • @ConditionalOnResource-there are specified resources in the Classpath
  • @ConditionalOnWebApplication-This is a web application
  • @ConditionalOnNotWebApplication-this is not a web application

@SpringBootApplication

  1. This is the main class startup annotation of springboot, generally as follows

    @SpringBootApplication
    public class SpringBootDemoApplication extends SpringBootServletInitializer {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBootDemoApplication.class, args);
        }
    }
     
  2. @SpringBootApplication is declared as follows

    @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 {
       //
    }
     
  3. The parent annotation @SpringBootConfiguration is equivalent to the @Configuration annotation, declared as a configuration class

  4. Parent annotation @ComponentScan configures additional package scanning paths

  5. The parent annotation @EnableAutoConfiguration is the main automatic configuration annotation, defined as follows

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
       // 
    }
     
  6. @AutoConfigurationPackage annotation is mainly to automatically load some jar package beans, defined as follows

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @Import(AutoConfigurationPackages.Registrar.class)
    public @interface AutoConfigurationPackage {
    
    }
    
    
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {
       //    
       //
        register(registry, new PackageImport(metadata).getPackageName());
    }
     
  7. @Import(AutoConfigurationImportSelector.class) introduces the automatic configuration class package, the relevant execution code is as follows

    //spring.factories 
    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
    		AnnotationAttributes attributes) {
    	List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
    			getSpringFactoriesLoaderFactoryClass(), 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;
    }
     
  8. The classes declared in spring.factories all follow the Condition to determine whether to load into a bean, such as the DataSourceAutoConfiguration class, which is partially defined as follows

    @Configuration
    @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
    @EnableConfigurationProperties(DataSourceProperties.class)
    @Import({ DataSourcePoolMetadataProvidersConfiguration.class,
            DataSourceInitializationConfiguration.class })
    public class DataSourceAutoConfiguration {
    
        @Configuration
        @Conditional(EmbeddedDatabaseCondition.class)
        @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
        @Import(EmbeddedDataSourceConfiguration.class)
        protected static class EmbeddedDatabaseConfiguration {
    
        }
    
        @Configuration
        @Conditional(PooledDataSourceCondition.class)
        @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
        @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
                DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
                DataSourceJmxConfiguration.class })
        protected static class PooledDataSourceConfiguration {
    
        }
    }
     

Custom configuration

Override automatic configuration

In the automatic configuration, many of them are judged based on ConditionalOnMissingBean. When we customize this bean, he will not use automatic configuration, such as some configuration in DataSourceAutoConfiguration:

@Configuration
@Conditional(EmbeddedDatabaseCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import(EmbeddedDataSourceConfiguration.class)
protected static class EmbeddedDatabaseConfiguration {

}
 

External configuration via property file

There are many ways to set up Spring Boot applications. Spring Boot can obtain attributes from a variety of attribute sources. High priority can override low priority attributes. The priority order from high to low is as follows:

  1. Command line parameters
    java -jar readinglist-0.0.1-SNAPSHOT.jar --spring.main.show-banner=false
     
  2. JNDI attributes in java:comp/env
  3. JVM system properties
  4. Operating system environment variables
    export spring_main_show_banner=false
     
  5. Randomly generated attributes prefixed with random.* (you can refer to them when setting other attributes, such as ${random. long})
  6. Application.properties or appliaction.yml files outside the application
    spring.main.show-banner=false
    
    spring:
        main:
        show-banner: false
     
  7. The application.properties or appliaction.yml file packaged in the application
  8. Property source annotated by @PropertySource
  9. Default attribute

The application.properties and application.yml files can be placed in the following four locations, with priority from high to low as follows

  1. External, in the/config subdirectory relative to the application running directory
  2. External, in the directory where the application runs
  3. Built-in, in the config package
  4. Built-in, in the root of the Classpath