標籤:編譯 過濾 basedir bind component pid 收集 object nbsp
學了將近兩個月的spring後,最近又在學習springBoot,發現springBoot可真是太好用了啊,於是就把自己的理解以及收集的資料記錄下來,寫了這個部落格,來協助大家學習如何使用springBoot。
其實作為一個spring的架構,spring的底層也是IOC和DI機制,至於是如何具體實現的,我下面會做一下說明(下面很多都是我從網上的資料參考的,如果有不全或錯誤的地方,希望大家能給予補充和修改)
使用spring的第一步當然是匯入jar包了,不過和spring匯入jar包的方式是完全不同的,spring需要一個一個的匯入jia包,springBoot只需要匯入一個依賴,就能自動載入所有相關的包了,下面我們先來看看寫一個helloworld的pom.xml吧。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yc.springBoot8</groupId> <artifactId>testSpringBoot8</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>testSpringBoot8 Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <java.version>1.8</java.version> </properties> <!-- 官方配置好的一些資訊,可以自己配 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> </parent> <!-- web項目的依賴 --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <finalName>testSpringBoot8</finalName> </build></project>
其中,<parent>裡面的是一些官方封裝好的配置,包含以下這些內容:
1、使用java6編譯層級
2、使用utf-8編碼
3、實現了通用的測試架構 (JUnit, Hamcrest, Mockito).
4、智能資源過濾
5、智能的外掛程式配置(exec plugin, surefire, Git commit ID, shade).
作為一個初學者,完全可以使用官方給的這些配置,如果你要不用也是可以自己配的。我唯一改的是java的編譯版本,因為我用的是jdk8,只要添加一個<java.vwesion>就行了。
下面我們就來看看匯入了一個web包依賴後,到底匯入了哪些jar包吧:
點開這個spring-boot-starter-web後我們可以看到裡面沒有任何包,只有一些配置資訊,開啟裡面的pom.xml,裡面的內容是:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starters</artifactId> <version>1.5.4.RELEASE</version> </parent> <artifactId>spring-boot-starter-web</artifactId> <name>Spring Boot Web Starter</name> <description>Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container</description> <url>http://projects.spring.io/spring-boot/</url> <organization> <name>Pivotal Software, Inc.</name> <url>http://www.spring.io</url> </organization> <properties> <main.basedir>${basedir}/../..</main.basedir> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> </dependencies></project>
這個pom.xml裡面就有很多jar包的配置,沒錯,這些都是會自動匯入我們項目的jar包,springBoot就是通過這樣的方式來自動匯入jar包的。
導完包後就要開始寫代碼了。
任何一個Spring Boot項目,都會有一個啟動類作為主程式入口,我寫的啟動類是:Application.class,啟動類上要有@SpringBootApplication註解。
package com.yc;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
//啟動類public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
@SpringBootApplication註解主要包含以下三個註解
其中最重要的是@EnableAutoConfiguration,
@EnableAutoConfiguration是藉助@Import的協助,將所有符合自動設定條件的bean定義載入到IoC容器
底層:從classpath中搜尋所有的META-INF/spring.factories設定檔,並將其中org.springframework.boot.autoconfigure.EnableutoConfiguration對應的配置項通過反射(Java Refletion)執行個體化為對應的標註了@Configuration的JavaConfig形式的IOC容器配置類,然後匯總為一個並載入到IOC容器。
@SpringBootConfiguration(內部為@Configuration):標註當前類是配置類,並會將當前類內聲明的一個或多個以@Bean註解標記的方法的執行個體納入到srring容器中,並且執行個體名就是方法名。
底層:當讀取到@Configuration以後,就會自動的讀取這個類裡面的方法,如果發現這個方法上面有@Bean註解的話,就取到這個方法的方法名,根據方法名啟用這個方法,得到一個傳回值,然後將方法名作為id,傳回值作為值,產生一個Bean存入Bean容器中,IOC完成。
@ComponentScan告訴Spring哪個packages的用註解的類會被spring自動掃描並且裝入bean容器中,一般將該啟動類放到根包路徑下,因為它會預設掃描該包路徑下的子包。所以包的結構最好寫成這樣:
SpringApplication的run方法的主要流程大體可以歸納如下:(這些都是我搬運來的,有興趣的瞭解一下,沒興趣的直接跳過,與使用SpringBoot無關)
??1、建立和配置環境
??根據初始化的配置建立environment的類型,包括配置要使用的PropertySource以及Profile。
??啟動監聽器的environmentPrepared方法,調用所有監聽器來監聽。
??如果SpringApplication的showBanner屬性被設定為true,則列印banner。
??2、建立ApplicationContext
??根據使用者是否明確設定了applicationContextClass類型以及初始化階段的推斷結果,決定該為當前SpringBoot應用建立什麼類型的ApplicationContext並建立完成,然後根據條件決定是否添加ShutdownHook,決定是否使用自訂的BeanNameGenerator,決定是否使用自訂的ResourceLoader,當然,最重要的,將之前準備好的Environment設定給建立好的ApplicationContext使用。
??3、載入資源,就是在初始化過程中source包含的類
??4、context 重新重新整理
??調用ApplicationContext的refresh()方法,完成IOC容器可用的最後一道工序。
??5、配置spring boot特有的單例bean 如commandline相關
??6、監聽器實現所有finished操作
??遍曆執行SpringApplicationRunListener的finished()方法。
??至此,Spring boot的啟動過程就完成了。
這一系列的步驟都在SpringApplication.class的源碼中有對應的代碼。
如果你只是想學一下簡單配置的話無視上面那段吧。
在你運行了Application.class以後,一個spring容器(Application Context)就建立好了,在建立容器的同時,這個類也偷偷摸摸幹了一些其他的事,比如它會掃描當前類上的依賴,然後它就發現了spring-webmvc在類路徑上(問題來了,這個東東是哪來的?其實它是我們在pom.xml中配置的spring-boot-starter-web傳遞引入的,仔細看的同學一定會發現上面pom.xml中有哦),因此Spring Boot判斷出這個項目是一個web應用,並啟動一個內嵌的Servlet容器(預設是Tomcat)用於處理HTTP請求。
如果你之前學過sprng mvc的話,就應該知道我們應該建一個controller來做http請求的分發的處理工作,沒學過也無所謂,反正我下面會講。。。
package com.yc.controllers;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HelloController { @RequestMapping("/hello") public String hello(){ return "spring boot, hello world!"; }}
上面的HelloController就是一個controller了,它的作用就是處理url為hello的http請求並將”spring boot, hello world!”顯示在網頁上了。
一個controller中一般有以下註解
@Controller:表示這個類是一個用來處理http請求的controller,只能作用在類上
@RequestMapping:配置url映射,既可以作用在類上也可以作用在方法上面,類級注釋的url會附加到方法級注釋的url上
@PathVariable :其用來擷取url 中的動態參數。
@RequestParam:將請求參數綁定到控制器的方法參數
@RequestBody:將HTTP請求體的值綁定到方法參數上,一般用來將請求體中的JSON字串綁定到相應的bean上
@ResponseBody:這個注釋可以放在方法上面,並指示傳回型別應該直接寫入HTTP響應體,一般用來返回json資料和xml,一旦使用了這個註解,就不會再走視圖處理器,而是直接將資料寫入到輸入資料流中。
@RestController:@RequestBody和@Controller結合體
現在@Controller已經很少使用了,一般都是使用@RestController,前台將json資料傳過來,controller接受到資料以後,通過@RequestBody註解將資料繫結到Bean或者方法參數上,處理資料後,通過@ResponseBody再將處理的結果轉成json資料傳給後台,以達到解耦的目的。
當然,雖然大多使用的是@RestController,但是@Controller也有它特有的作用,一個類使用@Controller註解時,並且這個類中方法沒有@ResponseBody註解時,就會有不同大傳回型別,我簡單點的介紹兩種常用的。如果返回的是一個”String”類型,那麼就會通過視圖解析器,跳轉到一個jsp或者html或者其他介面上,跳轉到哪由配置決定(視圖解析器和它的配置下面會講)。如果是返回的是”ModelAndView”類型的話,ModelAndView主要有兩個方法,setViewName()方法可以設定返回的視圖的名稱,addObject()可以設定需要返回的值。至於其它的傳回值想瞭解的可以看spring的官方文檔我就不一一解釋了。如果這個這個方法上面有了@ResponseBody註解的話,那就不好意思了,不管返回什麼,都會被直接寫入輸入資料流了。
如果你完成了上面幾步,只要先運行Application.java,並在瀏覽器裡輸入http://localhost:8080/hello,你就會在螢幕看到”spring boot, hello world!”,controller會接受到hello這個http請求,然後將傳回值”spring boot, hello world!”直接寫入了輸出資料流,所以才會直接顯示在螢幕上。大功告成,一個hellowrld就寫完了。
今天就寫到這了,至於如何整合mybatis,資料庫連接池等一些東西,過兩天再寫。
springBoot快速入門