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項目可加速建構項目