Springboot 2 learning notes

Description: refer to Raytheon springboot2 in station b
Video reference
Note reference

1, Basic introduction

1. SpringBoot benefits

  • Create a stand-alone Spring application

  • Embedded web server

    Previously, you need to package the war package and put it into tomcat to run

  • Automatic starter dependency to simplify build configuration

    starter, automatic dependency

  • Automatically configure Spring and third-party functions

  • Provide production level monitoring, health inspection and external configuration

  • No code generation, no need to write XML

SpringBoot is a one-stop framework that integrates the Spring technology stack

SpringBoot is a rapid development scaffold that simplifies the Spring technology stack

2. SpringBoot disadvantages

  • The iteration is fast and needs to pay attention to changes all the time
  • The package is too deep, the internal principle is complex, and it is not easy to master

3. Background of the times

Microservices, distributed, cloud native

2, HelloWord

1. Version requirements

Maven3.5+
Gradle6.8.x, 6.9.x, and 7.x

2,maven

Configure Alibaba cloud warehouse to download faster
<mirrors>
      <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
      </mirror>
  </mirrors>
 
  <profiles>
         <profile>
              <id>jdk-1.8</id>
              <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>1.8</jdk>
              </activation>
              <properties>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
                <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
              </properties>
         </profile>
  </profiles>

3. Create project

Note that maven is configured in idea

pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
</parent>

<!-- add to web rely on-->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Main function

package com.mys.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);
    }

}
//Business logic
package com.mys.boot.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

//@ResponseBody / / the data returned by each method is directly returned to the browser instead of jump
//@Controller
@RestController //Contains @ ResponseBody @Controller
public class HelloController {

    @RequestMapping("/hello")
    public String handle01() {
        return "hello";
    }
}

Spring Boot unified configuration file: application.properties

server.port=8888

Simplify deployment: install the plug-in, type the project into a jar package, and execute it directly on the target server

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
</build>

3, Automatic configuration principle

1. Dependency management

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
</parent>

His parent project
 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.3.4.RELEASE</version>
  </parent>

It declares the version number of almost all dependencies commonly used in development,Automatic version arbitration mechanism

You can modify the default version number

1,see spring-boot-dependencies It specifies the current dependent version key. 
2,Rewrite the configuration in the current project
    <properties>
        <mysql.version>5.1.43</mysql.version>
    </properties>

2. Scene launcher

1,See a lot spring-boot-starter-* :  *Just some kind of scene
2,Just introduce starter,We will automatically introduce all the dependencies required for this scenario
3,SpringBoot All supported scenarios
https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
4,See  *-spring-boot-starter:  The third party provides us with a scenario launcher to simplify development.
5,The lowest level dependency of all scenario initiators
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.3.4.RELEASE</version>
  <scope>compile</scope>
</dependency>

1,By default, no version can be written when importing dependencies
2,Introducing non version arbitrations jar,To write the version number.

3. Auto configuration

  • Automatically configure tomcat

1. Introduce tomcat dependency

2. Configure tomcat

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
  <version>2.3.4.RELEASE</version>
  <scope>compile</scope>
</dependency>
  • Automatically configure spring MVC

    1. Introduce a complete set of spring MVC components

    2. Automatically configure common spring MVC components

  • Automatically configure common web functions, such as character coding

    Spring boot configures all common scenarios for web development

  • Default package structure

    The package where the main program is located and the components of all its sub packages will be scanned by default. There is no need to configure the previous package scanning

    • To change the scanning path, @ SpringBootApplication(scanBasePackages = "com.atguigu")

    • Or * * @ ComponentScan * * specify the scan path

      @SpringBootApplication
       Equivalent to
      @SpringBootConfiguration
      @EnableAutoConfiguration
      @ComponentScan("com.mys.boot")
      
  • Various configurations have default values

    • The default configuration is ultimately mapped to a class, such as MultipartProperties

      The value of the configuration file will eventually be bound to each class, which will create objects in the container

      To change the default property value, modify the corresponding value in application.properties

  • Load all auto configuration items on demand

    • What scenarios are introduced and the automatic configuration of this scenario will be enabled
    • All spring boot autoconfigure functions are in the spring boot autoconfigure package

4. Container

4.1 component addition

1,@Configuration

Full(proxyBeanMethods = true)      Usage scenario: component dependency
Lite(proxyBeanMethods = false)
If only a component is registered in the container and others do not rely on this component, select false,This can speed up container startup
package com.mys.boot.config;

import com.mys.boot.bean.Pet;
import com.mys.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 1.The @ Bean annotation is used in the configuration class to register components for the container on the method. The default is single instance
 * 2.The configuration class itself is also a component
 * 3.proxyBeanMethods: Method of proxy bean
 */

@Configuration(proxyBeanMethods = false)//Tell springboot that this is a configuration class = = configuration file
public class MyConfig {
    /**
     * Add a component to the container, take the method name as the component id, the return type is the component type, and the return value is the instance of the component in the container
     * No matter how many external calls are made to the component registered in the configuration class, the single instance object previously registered in the container is obtained
     * @return
     */
    @Bean
    public User user01() {
        User user = new User("zhangshan", 18);
        //The user component depends on the pet component
        user.setPet(tomcatPet());
        return user;
    }

    @Bean("tom")//If you do not want the method name as the component name, you can modify it
    public Pet tomcatPet() {
        return new Pet("tomcat");
    }
}
package com.mys.boot;

import com.mys.boot.bean.Pet;
import com.mys.boot.bean.User;
import com.mys.boot.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {

        //1. Return to IOC container
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2. Check the components in the container
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        //3. The components registered in the container are single instance
        Pet tom01 = run.getBean("tom", Pet.class);
        Pet tom02 = run.getBean("tom", Pet.class);
        System.out.println("Components:" + (tom01 == tom02));

        //4. Get the components of the configuration class in the container
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean);

        //5. Configure the class to call the components declared in the container to determine whether they are taken from the container or directly called
        //MyConfig proxy object calls method 
        //proxyBeanMethods defaults to true, indicating that the registered single instance object is taken from the container
        //If proxyBeanMethods=false is set, the MyConfig obtained from the container is not a proxy object
        User user1 = bean.user01();
        User user2 = bean.user01();
        System.out.println(user1 == user2);

        //6. Test component dependencies
        User user01 = run.getBean("user01", User.class);
        Pet tom = run.getBean("tom", Pet.class);
        System.out.println("User's pet:" + (user01.getPet() == tom));
    }
}

@Bean @Component @Controller @Service @Repository @ComponentScan

2,@Import

Import a component of the specified type and automatically create the imported component in the container. The default component name is the full class name

@Import({User.class, DBHelper.class})

3. Conditional assembly

ConditionalOnBean,ConditionalOnMissingBean

4. @ ImportResource("classpath:beans.xml") imports the spring configuration file

4.2 configuration binding

1,@ConfigurationProperties+@Component

package com.mys.boot.bean;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component//Only the components in the container have the functions provided by spring boot
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private String brand;
    private Integer price;
		......
}
//Set the property value in application.properties
mycar.brand=BYD
mycar.price=10000

2,@EnableConfigurationProperties

@EnableConfigurationProperties(Car.class)
//1. Enable the configuration binding function of car
//2. Automatically register the car component into the container
4.3 principle analysis

1. Boot load autoconfiguration class

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
  • @Springboot configuration stands for springboot

    @Configuration represents the current configuration class

  • @ComponentScan package scan

  • @EnableAutoConfiguration

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}

(1)@AutoConfigurationPackage autoconfiguration package

@Import(AutoConfigurationPackages.Registrar.class)//Import components into container
public @interface AutoConfigurationPackage {}
//Use Register to import a series of components into the container
    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

		//AnnotationMetadata: Annotation (AutoConfigurationPackage) meta information
		@Override
		public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            //Obtain the package name by using the annotation meta information, and encapsulate the package name into an array
			register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
		}

		@Override
		public Set<Object> determineImports(AnnotationMetadata metadata) {
			return Collections.singleton(new PackageImports(metadata));
		}

	}

Under the package of MainApplication

(2)@Import(AutoConfigurationImportSelector.class)

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
   if (!isEnabled(annotationMetadata)) {
      return NO_IMPORTS;
   }
   AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
   return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

1. Use getautoconfigurationentry (annotation metadata); Batch import some components into the container

2. Use list < string > configurations = getcandidateconfigurations (annotation metadata, attributes); Get all the components that need to be imported into the container (127 components)

3. Use factory loading to get all components

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
      getBeanClassLoader());
Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {

4. Load a file from META-INF/spring.factories.

Scan all META-INF/spring.factories files in our current system by default

spring-boot-autoconfigure-2.3.4.RELEASE.jar package also contains META-INF/spring.factories

It is written in the file that all configuration classes to be loaded into the container as soon as spring boot is started

spring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories

2. Turn on automatic configuration items on demand

Although all the automatic configurations of our 127 scenarios are loaded by default when they are started.

Xxxautoconfiguration is assembled according to the Conditional assembly rule (@ Conditional) and will be configured as needed.

3. Modify default configuration

    @Bean
    @ConditionalOnBean(MultipartResolver.class)  //There are components of this type in the container
	//There is no component with this name multipartResolver in the container
    @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) 
    public MultipartResolver multipartResolver(MultipartResolver resolver) {
            //If the method labeled @ Bean passes in an object parameter, the value of this parameter will be found from the container
            //SpringMVC multipartResolver.  Prevent the file upload parser configured by some users from not conforming to the specification
      // Detect if the user has created a MultipartResolver but named it incorrectly
      return resolver;
    }
Add a file upload parser to the container;

SpringBoot will configure all components at the bottom by default. However, if the user has configured it himself, the user's priority shall prevail

@Bean
  @ConditionalOnMissingBean
  public CharacterEncodingFilter characterEncodingFilter() {
    }

Summary:

  • SpringBoot loads all the autoconfiguration classes xxxxconfiguration first

  • Each automatic configuration class takes effect according to conditions, and will bind the value specified in the configuration file by default. Take it from xxproperties. xxxProperties is bound to the configuration file

  • The effective configuration class will assemble many components in the container

  • As long as these components are in the container, they are equivalent to these functions

  • Customized configuration

    • Users directly replace the underlying components with @ Bean
    • The user can modify the value of the configuration file obtained by this component. application.properties

Xxxxxxautoconfiguration - > component - > xxxxproperties - > get the value - > application.properties

5. Best practices

  • See which are automatically configured

    • After self analysis, the automatic configuration corresponding to the imported scenario generally takes effect
    • debug=true in the configuration file enables the automatic configuration report. Negative \ Positive
  • Need to modify

    Modify configuration items by referencing documents https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties

    Analyze yourself. Which of the configuration files are bound by xxproperties.

  • Custom add or replace components

  • @Bean,@Component. . .

  • Customizer xxxxxxcustomizer;

4, Development tips

1,Lombok

Simplify JavaBean development

1.Introduce dependency
<dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
</dependency>
2.settings Installing plug-ins under
@Data//get set
@ToString//toString
@AllArgsConstructor//Parametric constructor
@NoArgsConstructor//Parameterless constructor

@EqualsAndHashCode//Override HashCode

2,dev-tools

After the item or page is modified: Ctrl+F9;
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

3,spring initializr

Project initialization Wizard

Create project structure dependent main program classes

Tags: Java Spring Spring Boot

Posted on Sat, 30 Oct 2021 21:37:25 -0400 by Braveheart