Springboot 系列(一)Spring Boot 入門篇
注意:本 Spring Boot 系列文章基於 Spring Boot 版本 v2.1.1.RELEASE 進行學習分析,版本不同可能會有細微差別。
前言
由於 J2EE 的開發變得笨重,繁多的配置,錯亂的依賴管理,低下的開發效率,複雜的部署流程,第三方技術的整合難度較大等。同時隨著複雜專案的演進,微服務分散式架構思想逐漸進入開發者的視野。
1. Spring Boot 介紹
Spring Boot
提供了一組工具只需要極少的配置就可以快速的構建並啟動基於 Spring 的應用程式。解決了傳統 Spring 開發需要配置大量配置檔案的痛點,同時 Spring Boot
對於第三方庫設定了合理的預設值,可以快速的構建起應用程式。當然 Spring Boot
也可以輕鬆的自定義各種配置,無論是在開發的初始階段還是投入生成的後期階段。
2. Spring Boot 優點
- 快速的建立可以獨立執行的 Spring 專案以及與主流框架的整合。
- 使用嵌入式的 Servlet 容器,用於不需要打成war包。
- 使用很多的啟動器(Starters)自動依賴與版本控制。
- 大量的自動化配置,簡化了開發,當然,我們也可以修改預設值。
- 不需要配置 XML 檔案,無程式碼生成,開箱即用。
- 準生產環境的執行時應用監控。
- 與雲端計算的天然整合。
3. Spring Boot 前置
說了那麼多的 Spring Boot 的好處,那麼使用 Spring Boot 需要哪些前置知識呢?我簡單列舉了一下。
- Spring 框架的使用。
- Maven 構建工具的使用。
- IDEA 或其他開發工具的使用。
4. Spring Boot 體驗
現在我們已經瞭解了 Spring Boot 是什麼,下面我們將使用 Spring Boot 開發一個入門案例,來體驗 Spring Boot 開發姿勢是如何的優雅與迅速。
Spring Boot 官方已經為我們如何快速啟動 Spring Boot 應用程式提供了多種方式。
你可以在 Spring 官方網站直接生成專案下載匯入IDE進行開發。
https://start.spring.io/
也可以直接克隆 GitHub 上的初始專案進行體驗。
git clone https://github.com/spring-guides/gs-spring-boot.git cd gs-spring-boot/initial
這裡我們選擇後者,直接克隆進入到 initial 資料夾使用 maven 進行編譯啟動。
mvn package && java -jar target/gs-spring-boot-0.1.0.jar
第一次編譯需要下載需要的依賴,耗時會比較長,編譯完成之後緊接著可以看到 Spring 的啟動標誌。這時 Spring Boot 的 web程式已經執行在8080埠了。
$ curl -s localhost:8080 Greetings from Spring Boot!
5. Spring Boot 開發
下面手動編寫一個 Spring Boot 入門案例,快速的開發一個 web mvc 應用。
專案結構如下:
5.1 依賴項
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <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> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
spring-boot-starter-parent
是Spring Boot 的核心依賴,它裡面定義了各種在開發中會用到的第三方 jar 的版本資訊,因此我們在引入其他的 Spring Boot 為我們封裝的啟動器的時候都不在需要指定版本資訊。如果我們需要自定義版本資訊,可以直接覆蓋版本屬性值即可。
spring-boot-starter-web
提供 web 以及 MVC 和 validator 等web開發框架的支援。
spring-boot-starter-test
提供測試模組的支援。如 Junit,Mockito。
需要說明的是,Spring Boot 為我們提供了很多的已經封裝好的稱為啟動器(starter)的依賴項。讓我們在使用的時候不需要再進行復雜的配置就可以迅速的進行應用整合。所有的官方啟動器依賴可以在 這裡 檢視。
所有 官方 釋出的啟動器都遵循類似的命名模式; spring-boot-starter-*
,這裡 *
是指特定型別的應用程式。此命名結構旨在幫助您尋找啟動器。
注意:編寫自己的啟動器的時候不應該使用這種命名方式。
5.2 啟動類
@SpringBootApplication public class HelloApplication { public static void main(String[] args) { SpringApplication.run(HelloApplication.class, args); } @Bean public CommandLineRunner commandLineRunner(ApplicationContext ctx) { return args -> { // 開始檢查spring boot 提供的 beans System.out.println("Let's inspect the beans provided by Spring Boot:"); String[] beanNames = ctx.getBeanDefinitionNames(); Arrays.sort(beanNames); for (String beanName : beanNames) { System.out.println(beanName); } }; } }
@SpringBootApplication
註解是一個便利的註解,它包含了以下幾個註解。
@Configuration @EnableAutoConfiguration @EnableWebMvc @ComponentScan
5.3 控制器
@RestController public class HelloController { @RequestMapping("/") public String index() { return "Greetings from Spring Boot!"; } }
@RestController
是 @RestController
與 @ResponseBody
的結合體。
5.4 訪問測試
直接啟動 HelloApplication.java
類就可以在控制檯看到啟動輸出,然後訪問8080埠檢視啟動是否正常。
經過上面的例子,已經使用 Spring Boot 快速的建立了一個 web 應用並進行了簡單的訪問測試。
6. Spring Boot 單元測試
結合上面提到的 Spring Boot 啟動器知識,Spring Boot 已經為我們提供了豐富的第三方框架,測試框架也不例外。
匯入單元測試依賴。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
6.1 模擬請求測試
編寫單元測試
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * 單元測試 */ @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public class HelloApplicationTests { @Autowired private MockMvc mvc; @Test public void contextLoads() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string("Greetings from Spring Boot!")); } }
關於上面程式碼的一些說明。
- MockMvc 允許我們方便的傳送 HTTP 請求。
- SpringBootTest 方便的建立一個 Spring Boot 專案的測試程式。
執行沒有任何異常說明程式測試通過。
6.2 Spring Boot 整合測試
import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; import java.net.URL; /** * <p> * 嵌入式伺服器由隨機埠啟動webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT * 並且在執行時發現實際埠@LocalServerPort * * @Author niujinpeng * @Date 2018/12/4 15:02 */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class HelloApplicationTestBySpringBoot { @LocalServerPort private int port; private URL base; @Autowired private TestRestTemplate template; @Before public void setup() throws Exception { this.base = new URL("http://localhost:" + port + "/"); } @Test public void getHello() throws Exception { ResponseEntity<String> response = template.getForEntity(base.toString(), String.class); assert (response.getBody().equals("Greetings from Spring Boot!")); } }
嵌入式伺服器由隨機埠啟動 webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
並且在執行時使用註解 @LocalServerPort
發現實際埠。
執行測試類通過輸出。
2018-12-06 22:28:01.914INFO 14320 --- [o-auto-1-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]: Initializing Spring DispatcherServlet 'dispatcherServlet' 2018-12-06 22:28:01.914INFO 14320 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet: Initializing Servlet 'dispatcherServlet' 2018-12-06 22:28:01.937INFO 14320 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet: Completed initialization in 23 ms
文章程式碼已經上傳到 GitHub Spring Boot 入門案例 。