spring boot入門

spring boot的定位

Spring Boot并不是不對Spring功能上的增強,而是提供了一種快速使用Spring的方式

本節(jié)轉載自spring boot與spring mvc的區(qū)別是什么贵试?

Spring Boot與spring及spring mvc的關系

簡介

  • Spring 框架就像一個家族撼唾,有眾多衍生產品例如 boot蝌矛、security、jpa等等。但他們的基礎都是Spring 的 IOC(提供了依賴注入的容器)和 AOP(解決了面向橫切面的編程) 梭域,然后在此兩者的基礎上實現了其他延伸產品的高級功能酥夭。
  • Spring MVC是基于 Servlet 的一個 MVC 框架 主要解決 WEB 開發(fā)的問題
  • 因為 Spring 的配置非常復雜赐纱,各種XML、 JavaConfig熬北、hin處理起來比較繁瑣疙描。于是為了簡化開發(fā)者的使用,從而創(chuàng)造性地推出了Spring boot讶隐,約定優(yōu)于配置起胰,簡化了spring的配置流程

關系

  1. Spring 最初利用“工廠模式”(DI)和“代理模式”(AOP)解耦應用組件。
  2. 大家覺得挺好用巫延,于是按照這種模式搞了一個 MVC框架(一些用Spring 解耦的組件)效五,用開發(fā) web 應用( SpringMVC )。
  3. 然后有發(fā)現每次開發(fā)都寫很多樣板代碼烈评,為了簡化工作流程火俄,于是開發(fā)出了一些“懶人整合包”(starter),這套就是 Spring Boot讲冠。

所以瓜客,用最簡練的語言概括就是:
Spring 是一個“引擎”;
Spring MVC 是基于Spring的一個 MVC 框架 竿开;
Spring Boot 是基于Spring4的條件注冊的一套快速開發(fā)整合包谱仪。
spring mvc < spring <springboot

為什么用spring boot

功能

Spring Boot實現了自動配置,降低了項目搭建的復雜度否彩。
眾所周知Spring框架需要進行大量的配置疯攒,Spring Boot引入自動配置的概念,讓項目設置變得很容易列荔。Spring Boot本身并不提供Spring框架的核心特性以及擴展功能敬尺,只是用于快速枚尼、敏捷地開發(fā)新一代基于Spring框架的應用程序。也就是說砂吞,它并不是用來替代Spring的解決方案署恍,而是和Spring框架緊密結合用于提升Spring開發(fā)者體驗的工具。同時它集成了大量常用的第三方庫配置(例如Jackson, JDBC, Mongo, Redis, Mail等等)蜻直,Spring Boot應用中這些第三方庫幾乎可以零配置的開箱即用(out-of-the-box)盯质,大部分的Spring Boot應用都只需要非常少量的配置代碼,開發(fā)者能夠更加專注于業(yè)務邏輯概而。

Spring Boot只是承載者呼巷,輔助你簡化項目搭建過程的。如果承載的是WEB項目赎瑰,使用Spring MVC作為MVC框架王悍,那么工作流程和你上面描述的是完全一樣的,因為這部分工作是Spring MVC做的而不是Spring Boot乡范。

對使用者來說配名,換用Spring Boot以后,項目初始化方法變了晋辆,配置文件變了渠脉,另外就是不需要單獨安裝Tomcat這類容器服務器了,maven打出jar包直接跑起來就是個網站瓶佳,但你最核心的業(yè)務邏輯實現與業(yè)務流程實現沒有任何變化芋膘。

優(yōu)點

  • Spring Boot可以建立獨立的Spring應用程序
  • 內嵌了如Tomcat,Jetty和Undertow這樣的容器霸饲,也就是說可以直接跑起來为朋,用不著再做部署工作了
  • 可以自動配置Spring:無需再像Spring那樣搞一堆繁瑣的xml文件的配置
  • 提供了一些現有的功能,如量度工具厚脉,表單數據驗證以及一些外部配置這樣的一些第三方功能
  • 提供的POM可以簡化Maven的配置

spring Boot實例demo

程序入口

SpringApplication.run(App.class, args)

首先來創(chuàng)建src/main/java/ToutiaoApplication.java:

@SpringBootApplication
public class ToutiaoApplication {
    public static void main(String[] args) {
                       SpringApplication.run(ToutiaoApplication.class, args);
    }
}

程序的入口:SpringApplication.run(Application.class, args)习寸,SpringApplication是Spring Boot框架中描述Spring應用的類,它的run()方法會創(chuàng)建一個Spring應用上下文(Application Context)傻工。
另一方面它會掃描當前應用類路徑上的依賴霞溪,如果Spring Boot判斷這是一個Web應用,會啟動一個內嵌的Servlet容器(默認是Tomcat)用于處理HTTP請求中捆。

@SpringBootApplication

Spring Boot提供一個方便的 @SpringBootApplication 選擇鸯匹。該 @SpringBootApplication 注解等價于以默認屬性使用 @Configuration+@EnableAutoConfiguration+@ComponentScan

1. @Configuration

定義一個配置類,用@Configuration注解該類泄伪,等價于XML中配置beans殴蓬;用@Bean標注方法等價于XML中配置bean

public class SpringConfig {  

    @Bean  
    public Piano piano(){  
        return new Piano();  
    }  
    @Bean(name = "counter")   
    public Counter counter(){  
        return  new Counter(12,"Shake it Off",piano());  
    }  
} 

2. @EnableAutoConfiguration

啟動Spring MVC

3. @ComponentScan

啟用組件掃描

實現Hello World顯示

在controller目錄下創(chuàng)建一個IndexController 類(之后的方法除特殊說明,否則都是IndexController類中的方法)

@Controller
public class IndexController {
    @RequestMapping(path = {"/","/index"})
    @ResponseBody
    public String index(HttpSession session){
        return "Hello World" ;
    }
}

運行Application文件蟋滴,右鍵Run As -> Java Application染厅,之后打開瀏覽器輸入地址:http://127.0.0.1:8080/(或者http://127.0.0.1:8080/ index) 就可以看到Hello world痘绎。

@Controller

基于@Component注解,表明是控制類組件肖粮,輔助實現組件掃描简逮,組件掃描會自動找到@Controller注解對應的類,并將其聲明為Spring應用上下文的一個bean

@RequestMapping(value=”/”,method)

  • 作用
    @RequestMapping 注解為控制器指定可以處理那些URL 請求

@RequestMapping (value=”/”,method)尿赚,value值屬性指定了這個方法所要處理的請求路徑,method屬性細化了它所處理的HTTP方法(GET或者POST),例如

@RequestMapping(value = "/login", method = RequestMethod.POST)

獲取請求中信息

  • @RequestBody
    綁定請求對象蕉堰,Spring會幫你進行協(xié)議轉換凌净,將Json、Xml協(xié)議轉換成你需要的對象屋讶。
  • @ResponseBody
    標注任何對象冰寻,由Srping完成對象——協(xié)議的轉換
    在SpringMVC中皿渗,可以使用@RequestBody和@ResponseBody兩個注解斩芭,分別完成請求報文到對象和對象到響應報文的轉換,底層這種靈活的消息轉換機制乐疆,就是Spring3.x中新引入的HttpMessageConverter即消息轉換器機制划乖。
    //value與path都是別名,實質上是一樣的
    @RequestMapping(value = {"/profile/{groupId}/{userId}"})
    @ResponseBody
    //127.0.0.1:8080/profile/12/33?key=xx&type=33
    public String profile(
    @PathVariable("groupId") String groupId,
    @PathVariable("userId") int userId,
    @RequestParam(value = "key",defaultValue = "megustas") String key,
    @RequestParam(value = "type",defaultValue = "1") int type) {
        return String.format("GID{%s},UID{%d},KEY{%s},TYPE{%d}",groupId,userId,key,type);
    }

@RequestParam注解和@PathVariable注解的區(qū)別挤土,從字面上可以看出前者是獲取請求里邊攜帶的參數琴庵;后者是獲取請求路徑里邊的變量參數。

例如:

127.0.0.1/user/{userId}?userName=datiangou
  • userId是路徑上的變量
  • userName才是請求參數信息

@Pathvariable

通過 @PathVariable 可以將 URL 中占位符參數綁定到控制器處理方法的入參中:URL 中的{xxx}占位符可以通過@PathVariable("xxx") 綁定到操作方法的入參中仰美。

@RequestMapping("/pathVariable/{name1}")
public String pathVariable(@PathVariable("name1")String name2){
    System.out.println("hello "+name2);
    return "helloworld";
}

URL 中的{name1}占位符通過@PathVariable("name1") 綁定到操作方法的String name2入參中迷殿。

@RequestParam

獲取請求參數

模板

直接返回HTML代碼太復雜

在之前所有的@RequestMapping注解的方法中,返回值字符串都被直接傳送到瀏覽器端并顯示給用戶咖杂。但是為了能夠呈現更加豐富庆寺、美觀的頁面,我們需要將HTML代碼返回給瀏覽器诉字,瀏覽器再進行頁面的渲染懦尝、顯示。

一種很直觀的方法是在處理請求的方法中奏窑,直接返回HTML代碼导披,但是這樣做的問題在于——一個復雜的頁面HTML代碼往往也非常復雜,并且嵌入在Java代碼中十分不利于維護埃唯。更好的做法是將頁面的HTML代碼寫在模板文件中(此處使用Velocity模板語言)撩匕,渲染后再返回給用戶。

模板引擎

模板引擎是為了使用戶界面與業(yè)務數據分離而產生的墨叛,它可以生成特定格式的文檔止毕,用于網站的模板引擎就會生成一個標準的HTML文檔模蜡。

在MVC模式中,模板引擎的工作原理基本一樣扁凛,比如說以freemarker為例忍疾,如下圖:

模板 + 數據模型 = 輸出

可概括為一個公式:

模板 + 數據模型 = 輸出

    @RequestMapping(value = {"/vm"})
    public String news(Model model){
        model.addAttribute("value1", "vv1");
        List<String> colors = Arrays.asList(new String[]{"RED", "GREEN", "BLUE"});
        Map<String, String> map = new HashMap<String, String>();
        for (int i = 0; i < 4; ++i) {
            map.put(String.valueOf(i), String.valueOf(i * i));
        }
        model.addAttribute("colors", colors);
        model.addAttribute("map", map);
        model.addAttribute("user",new User("Megustas"));//傳遞自定義對象  
        return "news";//news.vm
    }

Model

后端與渲染之間鉸鏈的一個數據模型Model,通過Model向前臺視圖傳遞參數,Model中存入的數據在Velocity中直接使用

return "news";

返回值不再是ResponseBody,
在上述例子中谨朝,返回值”news”并非直接將字符串返回給瀏覽器卤妒,而是尋找名字為news的模板進行渲染,news.vm文件存放于resources/templates目錄下

Velocity簡單語法

1.標識Velocity的腳本語句 #

用來標識Velocity的腳本語句字币,包括#set则披、#if 、#else洗出、#end士复、#foreach、#end翩活、#iinclude阱洪、#parse、#macro等

2. 用來標識一個變量$

3. 把不存在的變量顯示為空白!

4. 注釋##

5. 常用指令

常用指令 說明 例子
#include include指令用于引入其他的文件菠镇,引入的文件將會被當做靜態(tài)文件來處理 #include("test1.txt")
#parse 引入的文件通常是動態(tài)文件冗荸,并且parse指令中允許嵌套 ?
#set 賦值指令:可以用于創(chuàng)建一個新的實例,或者更新一個已經存在的實例利耍。set指令中也支持基本的數據運算 #set($username="yxd")
#if #else #end 條件判斷指令 ?
#foreach #end 循環(huán)指令 #foreach ($item in [1..5]).. #end
#macro #end 提供了一個構建模板代碼復用的機制俏竞,類似于Java中的函數 #macro ( sayHi $username)Hello $username #end

request/response

一次網頁請求中,通過request獲取它的所有數據

    @RequestMapping(value = {"/request"})
    @ResponseBody
    public String request(HttpServletRequest request,
                          HttpServletResponse response,
                          HttpSession session){
        //獲取Http請求的頭文件
        StringBuilder sb = new StringBuilder();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            sb.append(name + ":" + request.getHeader(name) + "<br>");
        }

        for(Cookie cookie : request.getCookies()){
            sb.append("Cookie");
            sb.append(cookie.getName());
            sb.append(":");
            sb.append(cookie.getValue());
            sb.append("<br>");
        }

        sb.append("getMethod:" + request.getMethod()+ "<br>");
        sb.append("getPathInfo:" + request.getPathInfo()+ "<br>");
        sb.append("getQueryString:" + request.getQueryString()+ "<br>");
        sb.append("getRequestURI" + request.getRequestURI());

        return sb.toString();
    }

Enumeration

Enumeration接口作用和Iterator類似堂竟,提供了遍歷元素的功能魂毁,其中只定義了兩種方法:

方法 作用
boolean hasMoreElements() 測試Enumeration對象中是否包含元素,如果有返回true出嘹,則表示至少包含一個元素
Object nextElement() 如果Enumeration對象還有元素席楚,返回對象的下一個元素,否則拋出NoSuchElementException

request.getQueryString():

request.getQueryString()就是獲取查詢字符串
即請求税稼?后面的就是QueryString烦秩,例如

127.0.0.1:8080/request?type=2&&k=xx
  • QueryString為type=2&&k=xx
  • RequestURI為/request

response

可以通過HttpServletResponse response將更多數據寫回

@RequestMapping(value = {"/response"})
@ResponseBody
public String response(
            @CookieValue(value="nowcoderid",defaultValue = "a") String nowcoderId,
            @RequestParam(value = "key", defaultValue = "key") String key,
            @RequestParam(value = "value", defaultValue = "value") String value,
            HttpServletResponse response){
    response.addCookie(new Cookie(key,value));
    response.addHeader(key,value);
    return "NowCoderId From Cookie:" + nowcoderId;
}

訪問:127.0.0.1:8080/response
輸出:NowCoderId From Cookie:a(此時為默認值)

訪問127.0.0.1:8080/response?key=nowcoderid&value=22:
輸出:NowCoderId From Cookie:22

重定向

redirect前綴,跳到首頁郎仆,默認是302跳轉
從一個頁面跳到另一個頁面只祠,所有的訪問都是同一個HttpSession,可以在redirect中添加session的一些特性扰肌,返回到首頁的時候抛寝,把session的信息讀取出來,顯示在首頁。用戶體驗較好盗舰。

301和302的區(qū)別
301:永久轉移
如果是301晶府,會把信息存入瀏覽器,下次瀏覽器訪問網址钻趋,會直接定位到另一個地方川陆。
302:臨時轉移

統(tǒng)一的異常處理

@ExceptionHandler

  • 統(tǒng)一處理某一類異常,從而能夠減少代碼重復率和復雜度
  • @ExceptionHandler只會是在當前的Controller里面起作用
    @RequestMapping("/admin")
    @ResponseBody
    public String admin(@RequestParam(value = "key",required = false) String key){
        if("admin".equals(key)){
            return "hello admin";
        }
        throw new IllegalArgumentException("Key 錯誤");
    }
    //好處是可以用統(tǒng)一的頁面處理問題
    @ExceptionHandler()
    @ResponseBody
    public String error(Exception e){
        return "error:" + e.getMessage();
    }

@ControllerAdvice

如果想所有的Controller統(tǒng)一處理異常的話蛮位,可以用@ControllerAdvice來創(chuàng)建一個專門處理的類较沪,這樣所有控制器的異常可以在一個地方進行處理

@ResponseStatus

  • 可以將某種異常映射為HTTP狀態(tài)碼
  • 不要輕易把@ResponseStatus修飾目標方法失仁,因為無論它執(zhí)行方法過程中有沒有異常產生购对,用戶都會得到異常的界面,而目標方法正常執(zhí)行

官方文檔

快速生成空項目文件

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末陶因,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子垂蜗,更是在濱河造成了極大的恐慌楷扬,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贴见,死亡現場離奇詭異烘苹,居然都是意外死亡,警方通過查閱死者的電腦和手機片部,發(fā)現死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門镣衡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人档悠,你說我怎么就攤上這事廊鸥。” “怎么了辖所?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵惰说,是天一觀的道長。 經常有香客問我缘回,道長吆视,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任酥宴,我火速辦了婚禮啦吧,結果婚禮上,老公的妹妹穿的比我還像新娘拙寡。我一直安慰自己授滓,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著褒墨,像睡著了一般炫刷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上郁妈,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天浑玛,我揣著相機與錄音,去河邊找鬼噩咪。 笑死顾彰,一個胖子當著我的面吹牛,可吹牛的內容都是我干的胃碾。 我是一名探鬼主播涨享,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼仆百!你這毒婦竟也來了厕隧?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤俄周,失蹤者是張志新(化名)和其女友劉穎吁讨,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體峦朗,經...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡建丧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了波势。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翎朱。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖尺铣,靈堂內的尸體忽然破棺而出拴曲,到底是詐尸還是另有隱情,我是刑警寧澤凛忿,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布疗韵,位于F島的核電站,受9級特大地震影響侄非,放射性物質發(fā)生泄漏蕉汪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一逞怨、第九天 我趴在偏房一處隱蔽的房頂上張望者疤。 院中可真熱鬧,春花似錦叠赦、人聲如沸驹马。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糯累。三九已至算利,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泳姐,已是汗流浹背效拭。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胖秒,地道東北人缎患。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像阎肝,于是被迫代替她去往敵國和親挤渔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內容