原文首發(fā)于『程序員精進』博客庸队,原文鏈接:『Java微服務實踐』201. 使用Spring Boot構建第一個API
得力于強力的Spring Boot框架,使得在Java領域開發(fā)微服務變得簡單輕松吊说。Spring Boot是個基于Spring依賴注入框架之上的快速開發(fā)及發(fā)布就緒(production-ready)框架局服,是在Java領域可以用來構建微服務的框架之一。在本文中將以實踐的方式來介紹Spring Boot框架浊竟,以及使用Spring Boot來構建RESTful風格的微服務怨喘。在最后我們再來看看Spring Boot框架里面哪些特性可以幫助我們構建發(fā)布就緒(production-ready)的微服務。以下是你在本文中將學到的內(nèi)容:
- 安裝最新Spring Boot開發(fā)環(huán)境
- 使用Spring Boot開發(fā)RESTful風格的微服務
- 使用Spring Boot特性來構建發(fā)布就緒(production-ready)的微服務
開發(fā)環(huán)境準備
在使用Spring Boot開發(fā)微服務之前需要安裝以下環(huán)境:
其它可選的IDE有IntelliJ IDEA, NetBeans和Eclipse振定,為了Spring Boot相關組件的引入必怜,所以本文就用STS來做演示了,同樣后频,依賴管理工具Maven也可以換成Gradle梳庆,根據(jù)你自己的熟悉程度來選了。在本文中的Spring相關框架版本為:
- Spring Boot 2.0.3.RELEASE
- Spring Framework 5.0.7.RELEASE
使用Spring Boot作為微服務框架進行微服務開發(fā)徘郭,為了方便使用Spring生態(tài)的各類框架和工具靠益,因此我們還需要準備相應的Spring Boot工具環(huán)境。
Spring Boot CLI快速開始
我們將使用Spring Boot CLI進行我們第一個Spring Boot應用的初始化残揉,當然你可以使用STS或Spring Initializr來進行創(chuàng)建胧后,這兩種方法我們將在后面介紹崔步,你日后可以根據(jù)自己的使用習慣來選擇咨跌。如果你使用STS作為IDE開發(fā)的話,使用STS構建Spring Boot應用很簡單,如果你習慣命令行操作的話惶楼,Spring Boot CLI是個不錯的選擇,如果你不想安裝STS或Spring Boot CLI的話屁商,直接使用Spring Initializr這是可以的榨崩。實際上Spring Boot CLI就是Spring Initializr的命令行版本。
當你安裝完畢Spring Boot CLI后竖伯,你可以通過命令行查看下安裝的版本情況存哲。
$ spring --version
Spring CLI v1.4.0.RELEASE
如果你能夠看到Spring CLI的版本信息,表明你的Spring Boot CLI已經(jīng)安裝完成七婴,接下來祟偷,我們使用Spring Boot CLI來創(chuàng)建個示例項目:
spring init --build maven --groupId io.junq.examples --version 1.0.0 --java-version 1.8 --dependencies web --name hello-springboot --package-name io.junq.examples.boot hello-springboot
在執(zhí)行完上面的命令后,會生成一個名為hello-springboot的目錄打厘,該目錄里面就是hello-springboot項目的完整文件了修肠。spring init命令還有一些可選參數(shù),我們列一些常用的出來簡單講述下:
--build
指定所使用的構建管理(依賴關系管理)工具户盯∏妒可選項為maven或gradle。
--groupId
maven項目的groupId莽鸭,會反映在pom.xml中吗伤,需要注意的是,設置了這個參數(shù)并不會指定包名蒋川,包名需要用 package-name參數(shù)來進行指定牲芋。
--package-name
應用的包名。
--version
應用的版本號捺球,如 1.0.0
--java-version
JDK版本
--dependencies
該應用依賴的Spring組件列表缸浦,可以選擇多個,以逗號分隔氮兵。
現(xiàn)在你可以進入hello-springboot目錄裂逐,執(zhí)行以下命令:
$ mvn spring-boot:run
如果不報錯的話,你的終端或命令行應該輸出類似以下日志:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.3.RELEASE)
2017-02-10 15:39:43.321 INFO 64362 --- [ main] i.j.e.boot.HelloSpringbootApplication : Starting HelloSpringbootApplication on junqiangs-MacBook-Pro.local with PID 64362 (started by junqiangliu in /Users/junqiangliu/Documents/james/courses/StuQ-1160 Java微服務/examples/hello-springboot)
2017-02-10 15:39:43.324 INFO 64362 --- [ main] i.j.e.boot.HelloSpringbootApplication : No active profile set, falling back to default profiles: default
2017-02-10 15:39:43.406 INFO 64362 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2e6aff98: startup date [Fri Feb 10 15:39:43 CST 2017]; root of context hierarchy
2017-02-10 15:39:44.538 INFO 64362 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration' of type [class org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-02-10 15:39:44.651 INFO 64362 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'validator' of type [class org.springframework.validation.beanvalidation.LocalValidatorFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-02-10 15:39:44.966 INFO 64362 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-02-10 15:39:44.981 INFO 64362 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2017-02-10 15:39:44.983 INFO 64362 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.11
2017-02-10 15:39:45.150 INFO 64362 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-02-10 15:39:45.151 INFO 64362 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1745 ms
2017-02-10 15:39:45.323 INFO 64362 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2017-02-10 15:39:45.329 INFO 64362 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-02-10 15:39:45.329 INFO 64362 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-02-10 15:39:45.329 INFO 64362 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-02-10 15:39:45.330 INFO 64362 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-02-10 15:39:45.627 INFO 64362 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2e6aff98: startup date [Fri Feb 10 15:39:43 CST 2017]; root of context hierarchy
2017-02-10 15:39:45.720 INFO 64362 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-02-10 15:39:45.722 INFO 64362 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-02-10 15:39:45.759 INFO 64362 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-02-10 15:39:45.759 INFO 64362 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-02-10 15:39:45.810 INFO 64362 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-02-10 15:39:46.001 INFO 64362 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-02-10 15:39:46.080 INFO 64362 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-02-10 15:39:46.085 INFO 64362 --- [ main] i.j.e.boot.HelloSpringbootApplication : Started HelloSpringbootApplication in 3.35 seconds (JVM running for 224.399)
現(xiàn)在你的第一個Spring Boot應用已經(jīng)成功運行泣栈,打開瀏覽器訪問 http://localhost:8080 卜高,你會看到如下內(nèi)容:
這個是一個默認的錯誤頁面,因為現(xiàn)在什么REST API代碼都還沒有編寫南片,所以正巢籼危咯。
STS快速開始
如果你不太習慣用命令行進行操作疼进,接下來會告訴你如何使用STS進行Spring Boot應用的創(chuàng)建薪缆。
- 首先我們打開STS程序,在菜單欄依次選擇 “文件(File) -> 新建(New)-> Spring Starter Project”伞广,如下圖:
- 接下來在創(chuàng)建項目窗口來設置項目信息拣帽,項目名稱為“hello-springboot”疼电、類型選“Maven”、Java版本為“1.8”减拭、Group Id為io.junq.examples蔽豺、Artifact為“hello-springboot”、包名為“io.junq.examples.boot”拧粪,注意此處的打包方式(Packaging)我們選擇了“jar”修陡,與傳統(tǒng)Web應用不同,微服務應用所運行的Java容器環(huán)境(指Tomcat既们、Jetty等)一般為自己內(nèi)嵌濒析,具體項目配置如下圖所示:
- 現(xiàn)在你會看到關于Spring組件的選擇,此處效果和Spring Boot CLI命令參數(shù)的--dependencies一樣的作用啥纸,在此選擇Web,然后點擊完成婴氮,如下圖所示:
- 此時你的項目列表窗口應該能夠看到你剛才創(chuàng)建的項目了斯棒,如下圖所示:
\
- 在“hello-springboot”項目上點擊右鍵,依次選擇“運行(Run As) -> Spring Boot App”主经,如下圖所示:
- 在不報錯的情況下荣暮,你這時應該在控制臺窗口看到如下畫面:
- 現(xiàn)在你的第一個Spring Boot應用已經(jīng)成功運行,打開瀏覽器訪問 http://localhost:8080 罩驻,你會看到如下內(nèi)容:
這個是一個默認的錯誤頁面穗酥,因為現(xiàn)在什么REST API代碼都還沒有編寫,所以正郴荻簦咯砾跃。
Hello World
我們現(xiàn)在已經(jīng)有了一個可以運行的Spring Boot應用,接下來我們添加一些簡單的方法來實現(xiàn)功能〗谒保現(xiàn)在我們來添加一個REST API抽高,路徑為 /api/hello,訪問此API時透绩,會返回“Hello world翘骂,Spring Boot rocks≈愫溃”的消息碳竟。首先定位到“src/main/java/io/junq/examples/boot”在該目錄下創(chuàng)建HelloRestController.java,該類負責 /api 這個API路徑的所有業(yè)務邏輯狸臣,如下所示:
public class HelloRestController {
public String hello() {
return "Hello world, Spring Boot rocks.";
}
}
添加 HTTP 請求入口
在上面我們創(chuàng)建了“HelloRestController”類想來它負責 /api 這個路徑下的業(yè)務請求莹桅,所以我們要給其添加 HTTP Endpoints 才能夠被Spring Boot框架正式處理,調(diào)用它來處理對應API路徑下的業(yè)務邏輯固棚,以下先介紹兩個關鍵的注解:
@RestController
??告訴 Spring 這個控制器類可以用來作為HTTP請求入口统翩,如GET仙蚜、POST、PUT厂汗、DELETE等委粉。
@RequestMapping
??表示將映射HTTP地址的哪個部分到Java代碼上,這里的Java代碼可以是類娶桦、方法等贾节。
我們將 “/api” 的HTTP請求入口綁定至 HelloRestController 這個控制器類上,將 “/api/hello” 映射到 “hello” 方法上衷畦,如下所示:
@RestController
@RequestMapping("/api")
public class HelloRestController {
@RequestMapping(method = RequestMethod.GET, value = "/hello",
produces = "text/plain")
public String hello() {
return "Hello world, Spring Boot rocks.";
}
}
這是再運行項目栗涂,使用瀏覽器訪問 http://localhost:8080/api/hello ,你會看到如下內(nèi)容:
附錄:環(huán)境安裝
以下的安裝教程以MacOS作為示例環(huán)境祈争,對于Linux用戶來說應該差不多斤程,對于Windows來說就不太一樣了。
Spring Boot CLI 安裝
Spring Boot CLI 2.0.3的安裝教程如下菩混,安裝過程來源于官方網(wǎng)站忿墅,大家想了解詳情,可以訪問沮峡。https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started-installing-spring-boot.html#getting-started-installing-the-cli
建議使用SDKMAN!進行安裝疚脐。
手動安裝
從Spring倉庫下載Spring CLI二進制文件,以下兩個壓縮包選擇一個即可:
下載完壓縮包解壓后邢疙,文件夾里面會有INSTALL.txt
文件棍弄,根據(jù)安裝指引文件進行安裝即可。
使用SDKMAN!安裝
安裝SDKMAN!
安裝SDKMAN!在Unix-Like的系統(tǒng)上十分簡單疟游,在Mac OSX, Linux, Cygwin, Solaris和FreeBSD系統(tǒng)上可以使用終端進行安裝呼畸,現(xiàn)在SDKMAN!安裝腳本現(xiàn)在支持Bash和ZSH。
$ curl -s "https://get.sdkman.io" | bash
當提示安全完成后乡摹,在終端中輸入以下命令役耕,將SDKMAN!添加到環(huán)境變量中。
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
然后便可以執(zhí)行sdk命令聪廉,進行版本查看瞬痘,版本查看返回版本號成功就代表SDKMAN!安裝成功了。
$ sdk version
SDKMAN 5.6.4+305
安裝Spring Boot CLI
$ sdk install springboot
$ spring --version
Spring Boot v2.0.3.RELEASE