最近因?yàn)轫?xiàng)目的緣故,需要接觸 spring boot,詳細(xì)的介紹可以參考官方的文檔,這里主要根據(jù)自己學(xué)習(xí)的實(shí)踐進(jìn)行簡(jiǎn)單分享。版本:1.3.6
簡(jiǎn)介
spring 框架是非常著名的 java 開(kāi)源框架,歷經(jīng)十多年的發(fā)展,整個(gè)生態(tài)系統(tǒng)已經(jīng)非常完善甚至是繁雜,spring boot 正是為了解決這個(gè)問(wèn)題而開(kāi)發(fā)的,為 spring 平臺(tái)和第三方庫(kù)提供了開(kāi)箱即用的設(shè)置,只需要很少的配置就可以開(kāi)始一個(gè) spring 項(xiàng)目。當(dāng)然,建議使用 java 8 來(lái)進(jìn)行開(kāi)發(fā)。
spring boot 實(shí)際上走的是 servlet 的路線,所以需要一個(gè) servlet 容器,什么 tomcat/jetty 都支持,比較意外的是居然還支持 undertow(undertow 大法好)。
安裝
簡(jiǎn)單粗暴直接上命令行,具體的簡(jiǎn)介參考注釋
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# 確定 java 版本 dawang:~ dawang$ java -version java version "1.8.0_91" java(tm) se runtime environment (build 1.8 .0_91-b14) java hotspot(tm) 64 -bit server vm (build 25.91 -b14, mixed mode) # 安裝 spring boot cli # 這是第一條語(yǔ)句 dawang:~ dawang$ brew tap pivotal/tap ==> tapping pivotal/tap cloning into '/usr/local/library/taps/pivotal/homebrew-tap' ... remote: counting objects: 16 , done. remote: compressing objects: 100 % ( 14 / 14 ), done. remote: total 16 (delta 2 ), reused 5 (delta 0 ), pack-reused 0 unpacking objects: 100 % ( 16 / 16 ), done. checking connectivity... done. tapped 9 formulae ( 50 files, 46 .1k) # 這是第二條語(yǔ)句 dawang:~ dawang$ brew install springboot ==> installing springboot from pivotal/tap ==> downloading https: //repo.spring.io/release/org/springframework/boot/spring-boot-cli/1.3.6.release/spring-boot-cli-1.3.6.release-bin.tar. ######################################################################## 100.0 % ==> caveats bash completion has been installed to: /usr/local/etc/bash_completion.d zsh completion has been installed to: /usr/local/share/zsh/site-functions ==> summary :beer: /usr/local/cellar/springboot/ 1.3 . 6 .release: 6 files, 8 .9m, built in 4 minutes 39 seconds |
然后我們就可以試試看 spring cli 的強(qiáng)大威力了!創(chuàng)建一個(gè)名為 app.groovy 的文件
1
2
3
4
5
6
7
|
@restcontroller class thiswillactuallyrun { @requestmapping ( "/" ) string home() { "hello world" } } |
只需要運(yùn)行 spring run app.groovy
即可!然而,在我的機(jī)器上并沒(méi)有這么順利, spring 已經(jīng)被 ruby 無(wú)情占用,只好在 .bashrc 中新建一個(gè)別名 alias springj="/usr/local/cellar/springboot/1.3.6.release/bin/spring
" ,然后用 springj run app.groovy
運(yùn)行。
還不行!打開(kāi) localhost:8080 的時(shí)候發(fā)現(xiàn)機(jī)器啟動(dòng)著 nginx,所以要先把 nginx 關(guān)掉,具體的步驟是
1
2
3
4
|
# 查找對(duì)應(yīng)的進(jìn)程號(hào) ps aux | grep nginx # 發(fā)送關(guān)閉信號(hào) kill -quit [nginx 主進(jìn)程 pid] |
解決掉各種攔路虎,我們?cè)俅芜\(yùn)行 springj run app.groovy ,就可以在瀏覽器中見(jiàn)到 hello world 了。
1
2
3
4
5
6
7
8
9
|
dawang$ springj run app.groovy resolving dependencies....... . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | ' _| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: spring boot :: (v1. 3.6 .release) |
最后我們需要安裝的有gradle 和 intellij idea ce ,這里就不贅述了,安裝好了我們就可以進(jìn)行下一步了
hello world
在 spring initializr 進(jìn)行簡(jiǎn)單設(shè)置即可生成項(xiàng)目模板,如下圖所示:
然后我們把下載的文件解壓并導(dǎo)入 intellij 中,稍作等待即可。
目錄結(jié)構(gòu)如上圖所示,我們直接運(yùn)行這個(gè) main 函數(shù)看看,控制臺(tái)中的輸出為
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | ' _| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: spring boot :: (v1. 3.6 .release) 2016 - 07 - 19 19 : 29 : 41.235 info 65812 --- [ main] wdx.helloworld.hellowordapplication : starting hellowordapplication on dawang.local with pid 65812 (/users/dawang/documents/dji/code/helloword/build/classes/main started by dawang in /users/dawang/documents/dji/code/helloword) 2016 - 07 - 19 19 : 29 : 41.239 info 65812 --- [ main] wdx.helloworld.hellowordapplication : no active profile set, falling back to default profiles: default 2016 - 07 - 19 19 : 29 : 41.320 info 65812 --- [ main] s.c.a.annotationconfigapplicationcontext : refreshing org.springframework.context.annotation.annotationconfigapplicationcontext @545997b1 : startup date [tue jul 19 19 : 29 : 41 cst 2016 ]; root of context hierarchy 2016 - 07 - 19 19 : 29 : 42.336 info 65812 --- [ main] o.s.j.e.a.annotationmbeanexporter : registering beans for jmx exposure on startup 2016 - 07 - 19 19 : 29 : 42.353 info 65812 --- [ main] wdx.helloworld.hellowordapplication : started hellowordapplication in 1.865 seconds (jvm running for 3.141 ) 2016 - 07 - 19 19 : 29 : 42.354 info 65812 --- [ thread- 1 ] s.c.a.annotationconfigapplicationcontext : closing org.springframework.context.annotation.annotationconfigapplicationcontext @545997b1 : startup date [tue jul 19 19 : 29 : 41 cst 2016 ]; root of context hierarchy 2016 - 07 - 19 19 : 29 : 42.356 info 65812 --- [ thread- 1 ] o.s.j.e.a.annotationmbeanexporter : unregistering jmx-exposed beans on shutdown process finished with exit code 0 |
當(dāng)然,因?yàn)槲覀兊某绦蛑袥](méi)有做任何操作,也沒(méi)有配合 web 模塊,所以加載 spring 完成之后就結(jié)束了。
我們看看項(xiàng)目對(duì)應(yīng)的 build.gradle ,其中只包含了兩個(gè)模塊:
1
2
3
4
|
dependencies { compile( 'org.springframework.boot:spring-boot-starter' ) testcompile( 'org.springframework.boot:spring-boot-starter-test' ) } |
其中:
- spring-boot-starter :核心模塊,包括自動(dòng)配置支持、日志和 yaml
- spring-boot-starter-test :測(cè)試模塊,包括 junit、hamcrest、mockito
我們加入 spring-boot-starter-web 模塊,對(duì)應(yīng)的 dependencies 部分為
1
2
3
4
5
|
dependencies { compile( 'org.springframework.boot:spring-boot-starter' ) compile( 'org.springframework.boot:spring-boot-starter-web' ) testcompile( 'org.springframework.boot:spring-boot-starter-test' ) } |
然后在 wdx.helloworld.web 這個(gè) package 中加入一個(gè) hellocontroller 類:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package wdx.helloworld.web; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.restcontroller; /** * created by dawang on 16/7/20. */ @restcontroller public class hellocontroller { @requestmapping ( "/hello" ) public string index() { return "hello world! this is wdxtub." ; } } |
再啟動(dòng)主程序,訪問(wèn) localhost:8080/hello 時(shí)就可以看到結(jié)果了:
然后我們編寫一下對(duì)應(yīng)的測(cè)試 hellowordapplicationtests (單詞拼錯(cuò)了不要在意這些細(xì)節(jié)),注意需要引入一些 static 方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package wdx.helloworld; import org.junit.before; import org.junit.test; import org.junit.runner.runwith; import org.springframework.boot.test.springapplicationconfiguration; import org.springframework.http.mediatype; import org.springframework.mock.web.mockservletcontext; import org.springframework.test.context.junit4.springjunit4classrunner; import org.springframework.test.context.web.webappconfiguration; import org.springframework.test.web.servlet.mockmvc; import org.springframework.test.web.servlet.request.mockmvcrequestbuilders; import org.springframework.test.web.servlet.setup.mockmvcbuilders; import wdx.helloworld.web.hellocontroller; import static org.springframework.test.web.servlet.result.mockmvcresultmatchers.*; import static org.hamcrest.matchers.equalto; @runwith (springjunit4classrunner. class ) @springapplicationconfiguration (classes = mockservletcontext. class ) @webappconfiguration public class hellowordapplicationtests { private mockmvc mvc; @before public void setup() throws exception { mvc = mockmvcbuilders.standalonesetup( new hellocontroller()).build(); } @test public void gethello() throws exception { mvc.perform(mockmvcrequestbuilders.get( "/hello" ).accept(mediatype.application_json)) .andexpect(status().isok()) .andexpect(content().string(equalto( "hello world! this is wdxtub." ))); } } |
具體測(cè)試簡(jiǎn)單來(lái)說(shuō)就是使用 mockservletcontext 來(lái)創(chuàng)建一個(gè)新的 webapplicationcontext ,然后我們就可以模擬訪問(wèn) localhost:8080/hello 了,運(yùn)行該測(cè)試,可以發(fā)現(xiàn)一切正常。
至此,我們就了解了如何開(kāi)始一個(gè) spring boot 項(xiàng)目,并編寫了一個(gè)簡(jiǎn)單的路由用來(lái)顯示對(duì)應(yīng)內(nèi)容。接下來(lái)我們會(huì)更多介紹開(kāi)發(fā)相關(guān)的其他知識(shí)。
starter poms
簡(jiǎn)單來(lái)說(shuō),starter poms 是方便我們快速給應(yīng)用添加功能的,只需要在 build.gradle 中包含對(duì)應(yīng)的 starter,可以省去大量的配置和依賴管理,下面是一些常用的 starter
- spring-boot-starter : 核心 spring boot starter,包括自動(dòng)配置支持,日志和 yaml
- spring-boot-starter-actuator : 監(jiān)控和管理應(yīng)用
- spring-boot-starter-remote-shell : 添加遠(yuǎn)程 ssh shell 支持
- spring-boot-starter-amqp : 高級(jí)消息隊(duì)列協(xié)議,通過(guò) spring-rabbit 實(shí)現(xiàn)
- spring-boot-starter-cloud-connectors : 簡(jiǎn)化在云平臺(tái)下服務(wù)的連接
- spring-boot-starter-elasticsearch : 對(duì) elasticsearch 搜索和分析引擎的支持
- spring-boot-starter-data-jpa : 對(duì) java 持久化 api 的支持,包括 spring-data-jpa , spring-orm 和 hibernate
- spring-boot-starter-data-mongodb : 對(duì) mongodb 的支持
- spring-boot-starter-mail : 對(duì) javax.mail 的支持
- spring-boot-starter-mobile : 對(duì) spring-mobile 的支持
- spring-boot-starter-redis : 對(duì) redis 的支持
- spring-boot-starter-security : 對(duì) spring-security 的支持
- spring-boot-starter-test : 對(duì)常用測(cè)試依賴的支持,包括 junit, hamcrest 和 mockito,還有 spring-test 模塊
- spring-boot-starter-web : 對(duì)全棧 web 開(kāi)發(fā)的支持,包括 tomcat 和 spring-webmvc
- spring-boot-starter-websocket : 對(duì) websocket 開(kāi)發(fā)的支持
- spring-boot-starter-ws : 對(duì) spring web service 的支持
如果想要切換容器和日志系統(tǒng)可以用下面的包
- spring-boot-starter-jetty : 導(dǎo)入 jetty http 引擎
- spring-boot-starter-log4j : 對(duì) log4j 日志系統(tǒng)的支持
- spring-boot-starter-logging : 導(dǎo)入 spring boot 的默認(rèn)日志系統(tǒng)
- spring-boot-starter-tomcat : 導(dǎo)入 spring boot 的默認(rèn) http 引擎
- spring-boot-starter-undertow : 導(dǎo)入 undertow http 引擎
更多社區(qū)貢獻(xiàn)的 starter poms 可以在 這里 查閱。
組織代碼最佳實(shí)踐
不要使用 default package ,建議使用反轉(zhuǎn)的域名來(lái)命名包
把 main 應(yīng)用類放在 root package 中,其他的類放在子包中,結(jié)構(gòu)如下所示
1
2
3
4
5
6
7
8
9
|
wdx +- helloworld +- helloworldapplication.java <- main class | +- web | +- hellocontroller.java | +- service | +- customerservice.java |
- spring boot 提倡在代碼中進(jìn)行配置。通常定義了 main 方法的類是使用 @configuration 注解的好地方
- 不需要將所有的 @configufation 放進(jìn)一個(gè)單獨(dú)的類中,可以使用 @import 注解可以導(dǎo)入其他的配置類。也可以用 @componentscan 注解自動(dòng)收集所有的組件,包括 @configuration 類
- 如果要使用基于 xml 的配置,也最好從 @configuration 類開(kāi)始,然后使用 @importresource 注解來(lái)加載 xml 配置文件
- spring boot 另一個(gè)很好的特性是會(huì)根據(jù)所添加的 jar 依賴來(lái)配置 spring 應(yīng)用,只需要簡(jiǎn)單把 @enableautoconfiguration 加入到 @configuration 類即可
- springbootapplication 注解默認(rèn)等價(jià)于 @configuration , @enableautoconfiguration 和 componentscan 這三個(gè)加起來(lái)的效果。
打包運(yùn)行
我們?cè)诮K端中執(zhí)行 gradle assemble 可以生成一個(gè) jar 包,也可以直接執(zhí)行這個(gè) jar 包來(lái)啟動(dòng)整個(gè)應(yīng)用,如
dawang:helloword dawang$ java -jar build/libs/helloword-0.0.1-snapshot.jar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | ' _| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: spring boot :: (v1. 3.6 .release) 2016 - 07 - 20 13 : 11 : 01.859 info 36943 --- [ main] wdx.helloworld.hellowordapplication : starting hellowordapplication on dawang.local with pid 36943 (/users/dawang/documents/dji/code/helloword/build/libs/helloword- 0.0 . 1 -snapshot.jar started by dawang in /users/dawang/documents/dji/code/helloword) 2016 - 07 - 20 13 : 11 : 01.864 info 36943 --- [ main] wdx.helloworld.hellowordapplication : no active profile set, falling back to default profiles: default 2016 - 07 - 20 13 : 11 : 01.960 info 36943 --- [ main] ationconfigembeddedwebapplicationcontext : refreshing org.springframework.boot.context.embedded.annotationconfigembeddedwebapplicationcontext @67424e82 : startup date [wed jul 20 13 : 11 : 01 cst 2016 ]; root of context hierarchy 2016 - 07 - 20 13 : 11 : 03.727 info 36943 --- [ main] s.b.c.e.t.tomcatembeddedservletcontainer : tomcat initialized with port(s): 8080 (http) 2016 - 07 - 20 13 : 11 : 03.750 info 36943 --- [ main] o.apache.catalina.core.standardservice : starting service tomcat 2016 - 07 - 20 13 : 11 : 03.752 info 36943 --- [ main] org.apache.catalina.core.standardengine : starting servlet engine: apache tomcat/ 8.0 . 36 2016 - 07 - 20 13 : 11 : 03.897 info 36943 --- [ost-startstop- 1 ] o.a.c.c.c.[tomcat].[localhost].[/] : initializing spring embedded webapplicationcontext 2016 - 07 - 20 13 : 11 : 03.897 info 36943 --- [ost-startstop- 1 ] o.s.web.context.contextloader : root webapplicationcontext: initialization completed in 1943 ms 2016 - 07 - 20 13 : 11 : 04.275 info 36943 --- [ost-startstop- 1 ] o.s.b.c.e.servletregistrationbean : mapping servlet: 'dispatcherservlet' to [/] 2016 - 07 - 20 13 : 11 : 04.282 info 36943 --- [ost-startstop- 1 ] o.s.b.c.embedded.filterregistrationbean : mapping filter: 'characterencodingfilter' to: [ /*] 2016-07-20 13:11:04.283 info 36943 --- [ost-startstop-1] o.s.b.c.embedded.filterregistrationbean : mapping filter: 'hiddenhttpmethodfilter' to: [/*] 2016-07-20 13:11:04.283 info 36943 --- [ost-startstop-1] o.s.b.c.embedded.filterregistrationbean : mapping filter: 'httpputformcontentfilter' to: [/*] 2016-07-20 13:11:04.284 info 36943 --- [ost-startstop-1] o.s.b.c.embedded.filterregistrationbean : mapping filter: 'requestcontextfilter' to: [/*] 2016-07-20 13:11:04.658 info 36943 --- [ main] s.w.s.m.m.a.requestmappinghandleradapter : looking for @controlleradvice: org.springframework.boot.context.embedded.annotationconfigembeddedwebapplicationcontext@67424e82: startup date [wed jul 20 13:11:01 cst 2016]; root of context hierarchy 2016-07-20 13:11:04.751 info 36943 --- [ main] s.w.s.m.m.a.requestmappinghandlermapping : mapped "{[/hello]}" onto public java.lang.string wdx.helloworld.web.hellocontroller.index() 2016-07-20 13:11:04.755 info 36943 --- [ 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) 2016-07-20 13:11:04.755 info 36943 --- [ 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) 2016-07-20 13:11:04.810 info 36943 --- [ main] o.s.w.s.handler.simpleurlhandlermapping : mapped url path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.resourcehttprequesthandler] 2016-07-20 13:11:04.810 info 36943 --- [ main] o.s.w.s.handler.simpleurlhandlermapping : mapped url path [/**] onto handler of type [class org.springframework.web.servlet.resource.resourcehttprequesthandler] 2016-07-20 13:11:04.875 info 36943 --- [ main] o.s.w.s.handler.simpleurlhandlermapping : mapped url path [/**/ favicon.ico] onto handler of type [ class org.springframework.web.servlet.resource.resourcehttprequesthandler] 2016 - 07 - 20 13 : 11 : 05.028 info 36943 --- [ main] o.s.j.e.a.annotationmbeanexporter : registering beans for jmx exposure on startup 2016 - 07 - 20 13 : 11 : 05.145 info 36943 --- [ main] s.b.c.e.t.tomcatembeddedservletcontainer : tomcat started on port(s): 8080 (http) 2016 - 07 - 20 13 : 11 : 05.151 info 36943 --- [ main] wdx.helloworld.hellowordapplication : started hellowordapplication in 4.0 seconds (jvm running for 4.484 ) |
當(dāng)然,因?yàn)樾枰械囊蕾嚕麄€(gè) jar 包會(huì)比較大。如果想要開(kāi)啟遠(yuǎn)程調(diào)試,命令為
1
|
java -xdebug -xrunjdwp:server=y,transport=dt_socket,address= 8000 ,suspend=n -jar build/libs/helloword- 0.0 . 1 -snapshot.jar |
gradle 運(yùn)行
當(dāng)然我們也可以簡(jiǎn)單使用內(nèi)置的 gradle 腳本來(lái)運(yùn)行,直接 gradle bootrun 即可。
配置 undertow
如果想要用 undertow 來(lái)替換默認(rèn)的 tomcat,也可以簡(jiǎn)單在 build.gradle 中進(jìn)行配置,比如:
1
2
3
4
5
6
7
8
9
|
configurations { compile.exclude module: "spring-boot-starter-tomcat" } dependencies { compile( 'org.springframework.boot:spring-boot-starter' ) compile( 'org.springframework.boot:spring-boot-starter-web' ) compile( 'org.springframework.boot:spring-boot-starter-undertow' ) testcompile( 'org.springframework.boot:spring-boot-starter-test' ) } |
然后使用 gradle bootrun 即可。
以上所述是小編給大家介紹的spring boot 快速入門指南,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!
原文鏈接:http://www.tuicool.com/articles/Rr6V7jn