天天看點

2021年5月27日——SpringBoot2基礎入門SpringBoot2——基礎入門

SpringBoot2——基礎入門

一、Spring 與 SpringBoot

1. SpringBoot優缺點

1.1 優點

  • 建立獨立Spring應用
  • 内嵌web伺服器
  • 自動starter依賴,簡化建構配置
  • 自動配置Spring以及第三方功能
  • 提供生産級别的監控、健康檢查及外部化配置
  • 無代碼生成、無需編寫XML

1.2 缺點

  • 人稱版本帝,疊代快,需要時刻關注變化
  • 封裝太深,内部原理複雜,不容易精通

2. 如何學習

官方參考文檔:Spring Boot Reference Documentation

版本新特性:Home · spring-projects/spring-boot Wiki · GitHub

二、SpringBoot2快速入門

1. 環境要求

  • Java 8 & 相容 java14 .
  • Maven 3.3+
  • idea 2019.1.2

2. 建立Hello工程

2.1 工程檔案

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.tiejiankudan</groupId>
    <artifactId>part01_quicklyStart</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 貌似不寫也不影響打包 -->
    <packaging>jar</packaging>

    <!-- 父工程作了很多版本控制(點開他的父工程就可以看到了) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>

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

    <build>
        <plugins>
        	<!-- 打包必備 -->    
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
           
  • 主程式:net.tiejiankudan.MainApplication
// 組合注解,預設掃描目前類所在的包及其子包,也可以通過 scanBasePackages 改變掃描範圍
@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
      SpringApplication.run(MainApplication.class, args);
    }
}
           
  • controller:net.tiejiankudan.controller.HelloController
// 相當于 @ResponseBody + @Controller 
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot 2";
    }
}
           
  • 因為內建tomcat,是以修改配置檔案就可以配置tomca了
  • application.properties

2.2 測試

運作 net.tiejiankudan.MainApplication 即可。

2.3 簡化部署

  • 打成jar包,使用mvn: package,千萬不要使用Plugins下jar打包,那個沒用
  • 運作jar包
java -jar 包路徑
           

三、了解自動配置原理

1. SpringBoot特點

  • 父項目做依賴版本管理
    • spring-boot-starter-parent =》spring-boot-dependencies
    • 想要改版本的話,找到spring-boot-dependencies裡定義好的标簽名,在自己的項目配置裡重寫即可
      <properties>
      	<mysql.version>5.1.43</mysql.version>
      </properties>
                 
  • starter場景啟動器自動導入所需jar包還做好了自動配置
    • spring-boot-starter-* 官方啟動器
    • *-spring-boot-starter 第三方啟動器
    • 啟動器大全:Using Spring Boot
    • 各種配置擁有預設值
      • 預設配置最終都是映射到某個類上,如:MultipartProperties
      • 配置檔案的值最終會綁定每個類上,這個類會在容器中建立對象
    • 按需加載所有自動配置項
      • 引入了哪些場景這個場景的自動配置才會開啟
      • SpringBoot所有的自動配置功能都在 spring-boot-autoconfigure 包裡面

2. 容器功能

2.1 元件添加

2.1.1 配置類

@Configuration

  • 聲明一個配置類,配置類也會加入到IOC容器
  • Full模式與Lite模式

net.tiejiankudan.config.Myconfig

// Full(proxyBeanMethods = true)
// Lite(proxyBeanMethods = false)
@Configuration(proxyBeanMethods = true)
public class Myconfig {
    @Bean
    public User user() {
        return new User();
    }
}
           

net.tiejiankudan.MainApplication

public class MainApplication {
    public static void main(String[] args) {
        // 1.傳回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        // 2.檢視容器中的元件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        // 3.從容器中獲得元件:不管是Lite還是Full都是同一個
        User user = run.getBean("user", User.class);
        User user2 = run.getBean("user", User.class);
        System.out.println("user1: " + user);
        System.out.println("user2: " + user2);

        // 通過配置元件建立對象: Lite不是同一個,Full是同一個
        Myconfig config = run.getBean(Myconfig.class);
        User user3 = config.user();
        User user4 = config.user();
        System.out.println(user3);
        System.out.println(user4);

        
        /************************************************************
         * 結論:
         *      proxyBeanMethods = true 時,
         *			調用建立Bean的方法時會檢測容器中是否已經存在Bean了,
         *			存在則直接用容器中的Bean
         *      proxyBeanMethods = false 時,
         *			則不會檢測,直接new出新的Bean,比true速度快,
         *			故稱之為Lite
         ************************************************************/
    }
}
           
2.1.2 添加Bean

@Bean、@Component、@Controller、@Service、@Repository

2.1.3 元件掃描

@ComponentScan

2.1.4 導入配置

@Import({Object1.class, Object2.class}):

  • 就是給容器中自動建立出這兩個類型的元件、預設元件的名字就是全類名
2.1.5 條件裝配

@Conditional:

  • 滿足Conditional指定的條件,則進行元件注入

net.tiejiankudan.config.Myconfig

@Configuration(proxyBeanMethods = true)
//@ConditionalOnBean(name = "tom")
@ConditionalOnMissingBean(name = "tom")
public class Myconfig {

}
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        Object tom = run.getBean("tom");
        Myconfig myconfig = run.getBean(Myconfig.class);
        System.out.println(tom);
        System.out.println(myconfig);
        
        
        /************************************************************
         * 結論:
         *      @ConditionalOnBean(name = "tom")生效時:
         *			容器中有叫tom的Bean時,Myconfig才被加入到容器中
         *      @ConditionalOnMissingBean(name = "tom")生效時:
         *			容器中沒有叫tom的Bean時,Myconfig才被加入到容器中
         		利用這個注解Spring-boot才能做到按需加載配置類進入容器
         ************************************************************/
    }
}
           

2.2、原生配置檔案引入

2.2.1 引入配置檔案

@ImportResource:

  • 引入SSM時期一直用的xml配置檔案,不過一定要注意配置檔案名不要命名成application.xml,這樣會報錯。

bean.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="tom" class="net.tiejiankudan.domain.User"></bean>
<bean id="jerry" class="net.tiejiankudan.domain.User"></bean>
</beans>
           

net.tiejiankudan.config.Myconfig

@Configuration(proxyBeanMethods = true)
@ImportResource("classpath:bean.xml")
public class Myconfig {

}
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        // 1.傳回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        Object tom = run.getBean("tom");
        Object jerry = run.getBean("jerry");
        System.out.println(tom);
        System.out.println(jerry);
        
        /************************************************************
         * 結果:
         *      [email protected]
		 *		[email protected]
         ************************************************************/
    }
}
           
2.2.2 配置綁定

如何使用Java讀取到properties檔案中的内容,并且把它封裝到JavaBean中,以供随時使用。

聲明成屬性類後,會出現個提示:

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-4NFHZQQ1-1622093046923)(D:\Document\Note\picture\002.jpg)]

不要讓他出現的話可以添加依賴:

<dependency>
	<groupId> org.springframework.boot </groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<!--不傳遞依賴-->
	<optional>true</optional>
</dependency>
           

方式一:@Component + @ConfigurationProperties(prefix = “xxx”)

net.tiejiankudan.property.CarProperties

// 加入到IOC容器中就可以自動配置屬性了,代替了之前的@PropertySource() + @Value 的做法
@Component
@ConfigurationProperties(prefix = "mycar")
public class CarProperties {
    private String brand;
    private Integer price;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}
           

application.properties

server.port=9000
mycar.brand=wulinghonguang
mycar.price=23333
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        // 1.傳回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        CarProperties carProperties = run.getBean(CarProperties.class);
        System.out.println(carProperties);
        
        
        /************************************************************
         * 結果:
         *      Car{brand='wulinghonguang', price=23333}
         ************************************************************/
    }
}
           

方式二:@EnableConfigurationProperties + @ConfigurationProperties(prefix = “xxx”)

net.tiejiankudan.property.CarProperties

// 注意 @Component 是被注釋了的
// @Component
@ConfigurationProperties(prefix = "mycar")
public class CarProperties {
    private String brand;
    private Integer price;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}
           

net.tiejiankudan.config.Myconfig

@Configuration(proxyBeanMethods = true)
// 下面的注解又把配置類加入到容器中
@EnableConfigurationProperties(CarProperties.class)
public class Myconfig {
    @Bean
    public Car car(CarProperties carProperties) {
        Car car = new Car();
        car.setBrand(carProperties.getBrand());
        car.setPrice(carProperties.getPrice());
        return car;
    }
}
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        // 1.傳回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        CarProperties carProperties = run.getBean(CarProperties.class);
        Car car = run.getBean(Car.class);
        System.out.println("carProperties: " + carProperties);
        System.out.println("car" + car);
        
        
        /************************************************************
         * 結果:
         *     carProperties: Car{brand='wulinghonguang', price=23333}
		 *	   carCar{brand='wulinghonguang', price=23333}
         ************************************************************/
    }
}
           

方式二: @ConfigurationProperties(prefix = “xxx”)

  • 思考:屬性類在容器中 =》容器自動注入屬性
  • 那麼:任何對象,隻要在容器中就可以自動注入屬性,那還要什麼屬性類(●’◡’●)

net.tiejiankudan.config.Myconfig

@Configuration(proxyBeanMethods = true)
public class Myconfig {
    @Bean
    @ConfigurationProperties(prefix = "mycar")
    public Car car() {
        return new Car();
    }
}
           

net.tiejiankudan.MainApplication

@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
    public static void main(String[] args) {
        // 1.傳回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        Car car = run.getBean(Car.class);
        System.out.println("car" + car);
        
        
        /************************************************************
         * 結果:
		 *	   carCar{brand='wulinghonguang', price=23333}
         ************************************************************/
    }
}
           

3. 自動配置原理

太複雜了,我暫時先跳過╮(╯-╰)╭

4. 開發小技巧

4.1 Lombok

簡化JavaBean開發

  • idea中搜尋安裝lombok插件
  • 在pom檔案中引入依賴

pom.xml

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
</dependency>
           
  • 在類上标明注解:
    • @NoArgsConstructor:自動加入無參構造
    • @AllArgsConstructor:自動加入全參構造
    • @Data:自動get/set方法
    • @ToString:自動加入tostring()方法
    • @EqualsAndHashCode:自動重寫equals和HashCode方法
    • @Slf4j:标注後該類裡就有了一個靜态屬性log

4.2 dev-tools

pom.xml

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-devtools</artifactId>
	<optional>true</optional>
</dependency>
           

項目或者頁面修改以後:Ctrl+F9重新建構項目。參考:Spring DevTools

4.3 Spring Initializr

項目建立的時候直接建立spring-boot項目可加速建構項目