Springboot快速上手
基於Springboot 2.0.0.RELEASE 版本
1. System Requirement
1. Java8 or higher
2. Spring Framework 5.0.4.RELEASE or higher□
3. Maven3.2 or higher
4. Servlet Container: Springboot embedded:
name |
Servlet Version |
Tomcat8.5(general) |
3.1 |
Jetty9.4 |
3.1 |
Undertow1.4 |
3.1 |
同時也支援部署到其它Servlet3.0+的容器中
2. 從hello world開始
1. 建立maven專案
2. springboot起步依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring‑boot‑starter‑parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring‑boot‑starter‑web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring‑boot‑starter‑test</artifactId> </dependency> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring‑boot‑maven‑plugin</artifactId> </plugin>
3. 構建專案結構
4. DemoApplication(啟動類)
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args);
}
}
5. HelloController
@RestController public class HelloController { @GetMapping("/hello") public ResponseEntity<String> hello(){ return new ResponseEntity<>("hello world", HttpStatus.OK); } }
3. 配置檔案
同時支援yml和properties格式配置檔案
支援萬用字元:application*.yml或application*.properties 載入順序:
1.在命令列中傳入的引數
2.SPRING_APPLICATION_JSON中的屬性。SPRING_APPLICATION_JSON是以JSON格式配置在系統環境變數中的
3. java:comp/env中的JNDI屬性
4. Java的系統屬性,可以通過System.getProperties()獲得的內容
5. 作業系統的環境變數
6. 通過random.*配置的隨機屬性
7. 位於當前應用jar包之外,針對不同{profile}環境的配置檔案內容,例如application‑{profile}.properties或是YAML定義的配置檔案
8. 位於當前應用jar包之內,針對不同{profile}環境的配置檔案內容,例如application‑{profile}.properties或是YAML定義的配置檔案
9. 位於當前應用jar包之外的application.properties和YAML配置內容
10. 位於當前應用jar包之內的application.properties和YAML配置內容
11. @Configuration注解修改的類中,通過@PropertySource註解定義的屬性
12. 應用預設屬性,使用SpringApplication.setDefaultProperties定義的內容
4. 日誌
Springboot預設整合的是logback,只會輸出到控制檯
可以在application配置檔案中配置輸出為日誌檔案(簡單配置)
如果想進行日誌檔案切割等複雜配置,可以自定義logback配置檔案
在resource下寫入logback‑spring.xml檔案,即可以被springboot載入
5. 配置資料庫連線池與ORM框架
Springboot2.0以後,預設整合HikariCP資料庫連線池 引入druid連線池和mybatis框架
新增依賴:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid‑spring‑boot‑starter</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis‑spring‑boot‑starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql‑connector‑java</artifactId>
</dependency>
配置檔案:
spring:
datasource:
url: jdbc:mysql://localhost:3306/toon?useSSL=false
username: root
password: 123456
driver‑class‑name: com.mysql.jdbc.Driver
mybatis:
config‑location: classpath:mybatis/mybatis‑config.xml
mapper‑locations: classpath:mapper/*Mapper.xml
6. 事務
通過註解@Transactional開啟事務
可以加在類上,表示整個類的方法都是開啟事務的,一般是更細粒度的加在方法(public 方法)上,表示這個方法是開啟事務的
@Transactional的引數:
name |
description |
readOnly |
該屬性用於設定當前事務是否為只讀事務,設定為true表示只讀,false則表示可讀 寫,預設值為false。例如:@Transactional(readOnly=true) |
rollbackFor |
該屬性用於設定需要進行回滾的異常類陣列,當方法中丟擲指定異常陣列中的異常時,則進行事務回滾。例如: 指定單一異常類:@Transactional(rollbackFor=RuntimeException.class) 指定多個異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class}) |
rollbackForClassName |
該屬性用於設定需要進行回滾的異常類名稱陣列,當方法中丟擲指定異常名稱陣列中的異常時,則進行事務回滾。例如: 指定單一異常類名稱: @Transactional(rollbackForClassName="RuntimeException") 指定多個異常類名稱:@Transactional(rollbackForClassName= {"RuntimeException","Exception"}) |
noRollbackFor |
該屬性用於設定不需要進行回滾的異常類陣列,當方法中丟擲指定異常陣列中的異常時,不進行事務回滾。例如: 指定單一異常類: @Transactional(noRollbackFor=RuntimeException.class) 指定多個異常類:@Transactional(noRollbackFor= {RuntimeException.class, Exception.class}) |
noRollbackForClassName |
該屬性用於設定不需要進行回滾的異常類名稱陣列,當方法中丟擲指定異常名稱陣列中的異常時,不進行事務回滾。例如: 指定單一異常類名稱: @Transactional(noRollbackForClassName="RuntimeException") 指定多個異常類名稱: @Transactional(noRollbackForClassName= {"RuntimeException","Exception"}) |
propagation |
指定事務的傳播行為: @Transactional(propagation=Propagation.REQUIRED) :如果有事務, 那麼加 入 事 務 , 沒 有 的 話 新 建 一 個 ( 默 認 情 況 下 ) @Transactional(propagation=Propagation.NOT_SUPPORTED) : 容 器 不 為這個方法開啟事務@Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事務,都建立一個新的事務,原來的掛起,新的執行完畢,繼續執行老的事務@Transactional(propagation=Propagation.MANDATORY) :必須在一個已有的事務中執行,否則丟擲異常@Transactional(propagation=Propagation.NEVER) :必須在一個沒有的事務 中 執 行 , 否 則 拋 出 異 常 ( 與 Propagation.MANDATORY 相 反 ) @Transactional(propagation=Propagation.SUPPORTS) :如果其他bean呼叫這個方法,在其他bean中宣告事務,那就用事務.如果其他bean沒有宣告事務,那就 不用事務. |
isolation |
該屬性用於設定底層資料庫的事務隔離級別,事務隔離級別用於處理多事務併發的情況,通常使用資料庫的預設隔離級別即可,基本不需要進行設定 @Transactional(isolation = Isolation.READ_UNCOMMITTED):讀取未提交資料(會出現髒讀, 不可重複讀) 基本不使用 @Transactional(isolation = Isolation.READ_COMMITTED):讀取已提交資料(會出現不可重複讀和幻讀) |
@Transactional(isolation = Isolation.REPEATABLE_READ):可重複讀(會出現幻讀) @Transactional(isolation = Isolation.SERIALIZABLE):序列化 |
|
timeout |
該屬性用於設定事務的超時秒數,預設值為‑1表示永不超時 |
7. 統一全域性異常處理
通過註解@ControllerAdvice標註一個類為全域性異常處理類
通過@ExceptionHandler標註一個方法為處理某異常的handler方法在方法中,可以自定義返回引數格式和內容
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({UserInvalidException.class})
public ResponseEntity<Response> handlerUserValidException(UserInvalidException e){
return new ResponseEntity<>(new Response(HttpStatus.BAD_REQUEST.value(),e.getMessage()),HttpStatus.BAD_RE
}
}
8. 依賴注入
Springboot使用JavaConfig的方式將指定的bean注入到IOC容器中,而不再使用xml配置的方式
JavaConfig方式通過註解@Configuration和@Bean來實現
任何一個標註了@Bean的方法,其返回值將作為一個bean定義註冊到Spring的IoC容器,方法名將預設成該bean定義 的id
可以類比於spring中xml的:
<beans>
<bean><bean>
</beans>
9. 依賴注入springboot提供的執行緒池通
過@EnableAsync開啟非同步
通過@Bean將ThreadPoolTaskExecutor注入
@Configuration @EnableAsync
public class ExecutorConfig {
@Bean
public ThreadPoolTaskExecutor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10); executor.setQueueCapacity(5000);
executor.setThreadNamePrefix("async‑service‑");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
10. 容器
Springboot預設內建Servlet容器Tomcat8.5
可以通過下面的方式替換為其他的容器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‑boot‑starter‑web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‑boot‑starter‑tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‑boot‑starter‑jetty</artifactId>
</dependency>
在使用內建容器後,可以直接打包成可以執行的jar,引入下面的外掛:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‑boot‑maven‑plugin</artifactId>
</plugin>
同時也可以打成war包,部署到外接的Servlet容器中
1. POM中增加配置:
<packaging>war</packaging>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‑boot‑starter‑web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‑boot‑starter‑tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‑boot‑starter‑tomcat</artifactId>
</dependency>
2. 增加ServletInitializer,將啟動類引導註冊,外部Web Application Context構建時,會新增啟動類
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DemoApplication.class);
}
}
11. 起步依賴和自動配置
啟動類註解@SpringbootApplication:
組合註解,相當於三個: @SpringbootConfiguration @EnableAutoConfi[email protected]
@SpringbootConfiguration 相當於@Configuration
1. @Configuration
JavaConfig的配置方式,被標註的類就被認為是IoC容器的配置類進行載入 所以啟動類也就是一個IoC容器配置類
2. ComponentScan
元件掃描配置,將符合要求的元件掃描然後加入IoC容器中
可以通過屬性scanBasePackages來更細粒度的指定掃描範圍
預設情況是掃描子包下的元件,所以啟動類一般就放在rootpackage下
3. EnableAutoConfiguration
通過@Import註解,將所有符合自動配置條件的bean載入到IoC容器中:
@Import({AutoConfigurationImportSelector.class})
自動配置的關鍵就是 AutoConfigurationImportSelector藉助於Spring的工具類SpringFactoriesLoader
SpringFactoriesLoader主要功能就是從指定的配置檔案META‑INF/spring.factories載入配置
配合@EnableAutoConfiguration使用的話,它更多是提供一種配置查詢的功能支援,即根據
@EnableAutoConfiguration的完整類名org.springframework.boot.autoconfigure.EnableAutoConfiguration
作為查詢的Key,獲取對應的一組@Configuration類
整個過程大致為:
從classpath中搜尋所有的META‑INF/spring.factories配置檔案,並將其中
org.springframework.boot.autoconfigure.EnableutoConfiguration對應的配置項通過反射例項化為對應的標註了@Configuration的JavaConfig形式的IoC容器配置類,然後彙總為一個並載入到IoC容器
SpringApplication.run()方法基本過程:
1. 方法中首先要建立一個SpringApplication物件例項,然後呼叫這個建立好的SpringApplication的例項方法。在
SpringApplication例項初始化的時候,它會提前做:
1> 根據classpath裡面是否存在某個特徵類
(org.springframework.web.context.ConfigurableWebApplicationContext)來決定是否應該建立一個為Web 應用使用的ApplicationContext型別
2> 使用SpringFactoriesLoader在應用的classpath中查詢並載入所有可用的ApplicationContextInitializer
3> 使用SpringFactoriesLoader在應用的classpath中查詢並載入所有可用的ApplicationListener
4> 推斷並設定main方法的定義類
2. SpringApplication例項初始化完成並且完成設定後,執行run方法的邏輯,首先遍歷執行所有通過
SpringFactoriesLoader可以查詢到並載入的SpringApplicationRunListener。呼叫它們的started()方法,相當於通知它們Springboot要準備開始啟動了
3. 建立並配置當前Spring Boot應用將要使用的Environment(包括配置要使用的PropertySource以及Profile)
4. 遍歷呼叫所有SpringApplicationRunListener的environmentPrepared()的方法,通知它們Springboot的Enviroment已經準備好了
5. 如果SpringApplication的showBanner屬性被設定為true,則列印banner
6. 根據使用者是否明確設定了applicationContextClass型別以及初始化階段的推斷結果,決定該為當前SpringBoot應用建立什麼型別的ApplicationContext並建立完成,然後根據條件決定是否新增ShutdownHook,決定是否使用自定義的BeanNameGenerator,決定是否使用自定義的ResourceLoader;最重要的是將之前準備好的Environment設 置給建立好的ApplicationContext使用。
7. ApplicationContext建立好之後,SpringApplication會再次藉助SpringFactoriesLoader,查詢並載入classpath中所有可用的ApplicationContext‑Initializer,然後遍歷呼叫這些ApplicationContextInitializer的initialize(applicationContext)方法來對已經建立好的ApplicationContext進行進一步的處理
8. 遍歷呼叫所有SpringApplicationRunListener的contextPrepared()方法
9. 整個啟動中最關鍵的步驟:將之前通過@EnableAutoConfiguration獲取的所有配置以及其他形式的IoC容器配置加載到已經準備完畢的ApplicationContext
10. 遍歷呼叫所有SpringApplicationRunListener的contextLoaded()方法
11. 呼叫ApplicationContext的refresh()方法,完成IoC容器可用的最後一道工序
12. 查詢當前ApplicationContext中是否註冊有CommandLineRunner,如果有,則遍歷執行
13. 正常情況下,遍歷執行SpringApplicationRunListener的finished()方法,如果整個過程出現異常,則依然呼叫所 有SpringApplicationRunListener的finished()方法,只不過這種情況下會將異常資訊一併傳入處理
說明:官方文件永遠是最好的入門教程。