對Spring Boot的開發(fā)環(huán)境進(jìn)行搭建,并對它的特點(diǎn)做進(jìn)一步的了解,才能更好地對Spring Boot有更深入的介紹。但是無論如何都需要先來搭建Spring Boot的工程。
搭建Spring Boot開發(fā)環(huán)境
使用Spring Boot,首先需要搭建一個(gè)快速開發(fā)的工程環(huán)境。
搭建Eclipse開發(fā)環(huán)境
首先找到Eclipse的菜單Help→Eclipse Marketplace,打開這個(gè)菜單后,可以看到一個(gè)新的窗口,然后選擇標(biāo)簽頁P(yáng)opular,從中找到Spring Tool Suite(STS)的插件,如圖1-1所示。
這樣就可以點(diǎn)擊安裝STS插件了,通過它可以很方便地引入Spring Boot的starter,而starter會引入對應(yīng)的依賴包和服務(wù)器,這樣就能夠幫助我們快速地搭建開發(fā)環(huán)境。
下面讓我們使用它創(chuàng)建一個(gè)工程。首先點(diǎn)擊熟悉的菜單File→New→Project,然后輸入spring過濾一些無關(guān)的內(nèi)容,再選用Spring Starter Project,點(diǎn)擊Next,創(chuàng)建項(xiàng)目,如圖1-2所示。
于是它會再打開一個(gè)新的對話框,如圖1-3所示。
圖2-3中畫框的地方是我根據(jù)自己需要進(jìn)行的自定義,其中選擇了使用War形式的打包,這意味著將使用的是一個(gè)帶有JSP工程的項(xiàng)目。在實(shí)際的操作中,讀者也需要根據(jù)自己的情況來定義它們。做完這些工作后,就可以點(diǎn)擊Next進(jìn)行下一步了,這樣它又會彈出另外一個(gè)窗口,如圖1-4所示。
圖1-1 安裝STS插件
圖1-2 創(chuàng)建Spring Boot工程
圖1-3 配置Spring Boot工程
圖1-4 選擇依賴的starter
這里選擇AOP和Web,只是做最簡單的項(xiàng)目而已,因此沒有引入太多的內(nèi)容。在現(xiàn)實(shí)的開發(fā)中,可能還需要選擇NoSQL開發(fā)工具,如redis、MongoDB等,還有數(shù)據(jù)庫,如MySQL,以及持久層Hibernate或者M(jìn)yBatis等項(xiàng)目的依賴,這些都是開發(fā)中經(jīng)常用到的。當(dāng)你選中所需要的包后,就可以直接點(diǎn)擊Finish,這個(gè)時(shí)候一個(gè)新的Spring Boot工程就建好了,如圖1-5所示。
圖1-5 新的Spring Boot工程
從圖1-5可以看到它是一個(gè)Maven項(xiàng)目,其中pom.xml文件已經(jīng)建好,而且給我們創(chuàng)建了帶有main方法的Chapter2Application.JAVA文件和初始化Servlet的ServletInitializer.java文件。這里通過Chapter2Application就可以運(yùn)行Spring Boot工程了。下面再打開工程中的pom.xml文件,就可以看到這些代碼,如代碼清單1-1所示。
代碼清單1-1 項(xiàng)目中的pom.xml文件
這些代碼是STS插件根據(jù)你選擇的starter依賴來創(chuàng)建的,這樣關(guān)于Eclipse搭建的開發(fā)環(huán)境就結(jié)束了。此時(shí)只需要使用Java Application的形式運(yùn)行Chapter2Application就可以啟動Spring Boot項(xiàng)目。
搭建IntelliJ IDEA開發(fā)環(huán)境
首先是啟動IntelliJ IDEA開發(fā)環(huán)境,然后選擇Create New Project,就可以看到一個(gè)新的窗口。我們選擇Spring Initializr,并且將JDK切換為你想要的版本,如圖1-6所示。
圖1-6 使用IntelliJ IDEA創(chuàng)建Spring Boot工程
點(diǎn)擊Next,也會彈出另外一個(gè)窗口,它將允許我們進(jìn)行一定的配置,如圖1-7所示。
圖1-7 配置Spring Boot項(xiàng)目
同樣,圖中加框的地方是我根據(jù)自己的需要進(jìn)行修改的內(nèi)容。注意,這里還是選擇了以War打包的形式,然后點(diǎn)擊Next,又到了可以選擇starter的窗口,如圖1-8所示。
圖1-8 選擇對應(yīng)的starter
也與Eclipse一樣,可以根據(jù)自己的需要選擇對應(yīng)的starter進(jìn)行依賴,IntelliJ IDEA也會為你建好工程,如圖1-9所示。
你也可以看到一個(gè)建好的類Chapter2Application、ServletInitializer和Maven的pom.xml文件。運(yùn)行Chapter2Application就可以啟動Spring Boot工程,而pom.xml則配置好了你選中的starter依賴,這樣就能夠基于IntelliJ IDEA開發(fā)Spring Boot工程了。
圖1-9 IntelliJ IDEA創(chuàng)建Spring Boot工程
到這里,如果你想使用Jetty或者Undertow作為服務(wù)器,又或者說你想切換后臺日志中的商標(biāo),那么可以參考附錄中的內(nèi)容。
Spring Boot的依賴和自動配置
在上節(jié)中已經(jīng)介紹了如何搭建Spring Boot工程,下面需要討論它為什么在很少的配置下就能夠運(yùn)行。
下面以最常用的Spring MVC為例進(jìn)行說明。首先打開Maven的本地倉庫,找到對應(yīng)Spring Boot的文件夾,可以看到圖1-10所示的目錄。
圖1-10 Spring Boot的Maven本地倉庫
這里先談spring-boot-start-web的內(nèi)容,未來還會談到spring-boot-autoconfigure文件夾的內(nèi)容,所以圖 1-10 中一并加了框。打開spring-boot-start-web文件夾,就可以看到一個(gè)名為spring-boot- starter-web-2.0.0.RELEASE.pom的文件,打開它就可以看到代碼清單1-2所示的代碼。
代碼清單1-2 spring-boot-starter-web的pom.xml文件
代碼中的中文注釋是我加入的。從這里可以看出,當(dāng)加入spring-boot-starter-web后,它會通過Maven將對應(yīng)的資源加載到我們的工程中,這樣便能夠形成依賴。但是這樣還不足以運(yùn)行Spring MVC項(xiàng)目,要運(yùn)行它還需要對Spring MVC進(jìn)行配置,讓它能夠生產(chǎn)Spring MVC所需的對象,才能啟用Spring MVC,所以還需要進(jìn)一步探討。
為了探討Spring MVC在Spring Boot自動配置的問題,首先在本地下載的Maven倉庫的目錄spring-boot-autoconfigure中找到
spring-boot-autoconfigure-2.0.0.RELEASE-sources.jar的包。它是一個(gè)源碼包,把它解壓縮出來,打開它目錄下的子目錄后,我們就可以看到許多配置類,如圖2-11所示。
圖1-11 Spring Boot的默認(rèn)配置類
這里可以看到存在很多的類,其中加框的類DispatcherServletAutoConfiguration就是一個(gè)對DispatcherServlet進(jìn)行自動配置的類。因?yàn)楸緯皇窃创a分析的書,所以不對注解這些內(nèi)容進(jìn)行深入的探討,只是截取DispatcherServletAutoConfiguration源碼中的一個(gè)內(nèi)部類DispatcherServletConfiguration對Spring Boot的自動配置做最基本的講解,如代碼清單1-3所示。
代碼清單1-3 部分源碼分析
注意上述代碼中加粗注解的注釋,這些中文注釋是我加入的,為的是更好地說明Spring Boot的自動配置功能。通過上面的代碼,可以看到Spring Boot內(nèi)部已經(jīng)自動為我們做了很多關(guān)于DispatcherServlet的配置,其中的@EnableConfigurationProperties還能夠在讀取配置內(nèi)容的情況下自動生成Spring MVC所需的類,有關(guān)這些內(nèi)容的討論可以參考附錄。到這里,應(yīng)該明白為什么幾乎在沒有任何配置下就能用Spring Boot啟動Spring MVC項(xiàng)目,這些都是Spring Boot通過Maven依賴找到對應(yīng)的jar包和嵌入的服務(wù)器,然后使用默認(rèn)自動配置類來創(chuàng)建默認(rèn)的開發(fā)環(huán)境。但是有時(shí)候,我們需要對這些默認(rèn)的環(huán)境進(jìn)行修改以適應(yīng)個(gè)性化的要求,這些在Spring Boot中也是非常簡單的,正如@EnableConfigurationProperties注解那樣,它允許讀入配置文件的內(nèi)容來自定義自動初始化所需的內(nèi)容,下節(jié)將探討這個(gè)問題。
使用自定義配置
上節(jié)討論了Spring Boot存在自動裝配組件和自定義的配置,這些它都給予了開發(fā)者默認(rèn)的約定配置項(xiàng)。關(guān)于這些內(nèi)容,可以在它公布的網(wǎng)址上看到所有的配置項(xiàng),網(wǎng)址是http://docs.spring.io/spring- boot/docs/current-SNAPSHOT/reference/htmlsingle/#appendix。這些配置項(xiàng)多達(dá)300多項(xiàng),所以十分繁復(fù),好在我們并不需要全部去配置,只是根據(jù)自己工程的需要引入對應(yīng)的starter,對其進(jìn)行必要的配置就可以了。
本書不會像流水賬那樣羅列這些配置項(xiàng),因?yàn)檫@些很無趣也沒有必要,而只是根據(jù)講解的需要,引入對應(yīng)的stater,才會討論對應(yīng)的配置項(xiàng)。將來在討論數(shù)據(jù)庫、NoSQL等內(nèi)容時(shí),才會討論對應(yīng)的配置項(xiàng)。這里需要我們記住的是通過這些約定的配置就可以在很大程度上自定義開發(fā)環(huán)境,以適應(yīng)真實(shí)需求。這就是Spring Boot的理念,配置盡量簡單并且存在約定,屏蔽Spring內(nèi)部的細(xì)節(jié),使得Spring能夠開箱后經(jīng)過簡單的配置后即可讓開發(fā)者使用,以滿足快速開發(fā)、部署和測試的需要。
如果你按照上述使用Eclipse或者IntelliJ IDEA進(jìn)行新建工程,那么可以在項(xiàng)目中發(fā)現(xiàn)它還會為你創(chuàng)建一個(gè)屬性文件application.properties,如圖2-12所示。
它是一個(gè)默認(rèn)的配置文件,通過它可以根據(jù)自己的需要實(shí)現(xiàn)自定義。例如,假設(shè)當(dāng)前8080端口已經(jīng)被占用,我們希望使用8090端口啟動Tomcat,那么只需要在這個(gè)文件中添加一行:
圖1-12 Spring Boot的配置文件
這樣以Java Application的形式運(yùn)行Chapter2Application就可以看到Spring Boot綁定的Tomcat的啟動日志:
注意,通過加粗的這行日志可以看到Tomcat是以8090端口啟動的,相信讀者明白了。也就是說,我們只需要修改配置文件,就能將開發(fā)的默認(rèn)配置變?yōu)樽远x配置。
事實(shí)上,Spring Boot的參數(shù)配置除了使用properties文件之外,還可以使用yml文件等,它會以下列的優(yōu)先級順序進(jìn)行加載:
命令行參數(shù);
來自java:comp/env的JNDI屬性;
Java系統(tǒng)屬性(System.getProperties());
操作系統(tǒng)環(huán)境變量;
RandomValuePropertySource配置的random.*屬性值;
jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置文件;
jar包內(nèi)部的application-{profile}.properties或application.ym(帶spring.profile)配置文件;
jar包外部的application.properties或application.yml(不帶spring.profile)配置文件;
jar包內(nèi)部的application.properties或application.ym(不帶spring.profile)配置文件;
@Configuration注解類上的@PropertySource;
實(shí)際上,yml文件的配置與properties文件只是簡寫和縮進(jìn)的差別,因此差異并不大,所以本書統(tǒng)一使用properties文件進(jìn)行配置。對于需要使用yml文件的讀者,只是需要稍加改動即可。
開發(fā)自己的Spring Boot項(xiàng)目
上面我們修改了服務(wù)器的啟動端口,有時(shí)候還需要修改Spring MVC的視圖解析器(ViewResolver)。Spring MVC的視圖解析器的作用主要是定位視圖,也就是當(dāng)控制器只是返回一個(gè)邏輯名稱的時(shí)候,是沒有辦法直接對應(yīng)找到視圖的,這就需要視圖解析器進(jìn)行解析了。在實(shí)際的開發(fā)中最常用的視圖之一就是JSP,例如,現(xiàn)在控制器中返回一個(gè)字符串“index”,那么我們希望它對應(yīng)的是開發(fā)項(xiàng)目的/WEB-INF/jsp/index.jsp文件。如果你還對Spring MVC不熟悉,那也沒有關(guān)系,未來我們還會談到它,這里的代碼很簡單,你只需要依葫蘆畫瓢就可以體驗(yàn)運(yùn)行Spring Boot項(xiàng)目了。下面的主要任務(wù)就是如果通過Spring Boot完成這個(gè)功能。首先我們需要在Maven的pom.xml中加入JSP和JSTL的依賴包,如代碼清單1-4所示。
代碼清單1-4 新增JSP和JSTL的Maven依賴配置
為了配置視圖解析器(ViewResolver),將application.properties文件修改為如代碼清單`-5所示。
代碼清單1-5 定義視圖前后綴
這里的spring.mvc.view.prefix和spring.mvc.view.suffix是Spring Boot與我們約定的視圖前綴和后綴配置,意思是找到文件夾/WEB-INF/jsp/下以.jsp為后綴的JSP文件,那么前綴和后綴之間顯然又缺了一個(gè)文件名稱,在Spring MVC機(jī)制中,這個(gè)名稱則是由控制器(Controller)給出的,為此新建一個(gè)控制器IndexController,其代碼如代碼清單1-6所示。
代碼清單1-6 開發(fā)控制器
這里定義了一個(gè)映射為/index的路徑,然后方法返回了“index”,這樣它就與之前配置的前綴和后綴結(jié)合起來找對應(yīng)的jsp文件,為此我們還需要開發(fā)一個(gè)對應(yīng)的jsp文件,為此我們先再建一個(gè)/webapp/WEB-INF/jsp/index.jsp文件,如代碼清單1-7所示。
代碼清單1-7 開發(fā)視圖(/webapp/WEB-INF/jsp/index.jsp)
這樣我們就完成了一個(gè)簡單的控制器,并且讓視圖解析器找到視圖的功能。從上面來看定義視圖解析器,在Spring Boot中只需要通過配置文件定義視圖解析器的前后綴即可,而無須任何代碼,這是因?yàn)镾pring Boot給了我們自定義配置項(xiàng),它會讀入這些自定義的配置項(xiàng),為我們生成Spring MVC中的視圖解析器。正如它所承諾的盡可能地配置Spring開發(fā)環(huán)境,然后再看到即將運(yùn)行Chapter2Application.java文件,如代碼清單1-8所示。
代碼清單1-8 Spring Boot運(yùn)行文件Chapter2Application
這里的注解@SpringBootApplication標(biāo)志著這是一個(gè)Spring Boot入門文件。加粗的代碼則是以Chapter2Application類作為配置類來運(yùn)行Spring Boot項(xiàng)目,于是Spring Boot就會根據(jù)你在Maven加載的依賴來完成運(yùn)行了。接下來我們以Java Application的形式運(yùn)行類Chapter2Application,就可以看到Tomcat的運(yùn)行日志。由于已經(jīng)把端口修改為了8090,因此打開瀏覽器后輸入http://localhost:8090/index,就可以看到運(yùn)行的結(jié)果如圖1-13所示。
圖1-13 測試視圖解析器
這樣我們就搭建完成Spring Boot的開發(fā)環(huán)境了。因?yàn)镾pring Boot是基于Spring原理基礎(chǔ)之上的,所以在討論Spring Boot時(shí),也十分有必要介紹Spring的技術(shù)原理,這樣才能知其然,亦知其所以然。