Spring中獲取request的幾種方法


前言

本文將介紹在Spring MVC開發(fā)的web系統(tǒng)中挂洛,獲取request對象的幾種方法礼预,并討論其線程安全性。

概述

在使用Spring MVC開發(fā)Web系統(tǒng)時(shí)虏劲,經(jīng)常需要在處理請求時(shí)使用request對象托酸,比如獲取客戶端ip地址荠藤、請求的url、header中的屬性(如cookie获高、授權(quán)信息)哈肖、body中的數(shù)據(jù)等。由于在Spring MVC中念秧,處理請求的Controller淤井、Service等對象都是單例的,因此獲取request對象時(shí)最需要注意的問題摊趾,便是request對象是否是線程安全的:當(dāng)有大量并發(fā)請求時(shí)币狠,能否保證不同請求/線程中使用不同的request對象。

這里還有一個(gè)問題需要注意:前面所說的“在處理請求時(shí)”使用request對象砾层,究竟是在哪里使用呢漩绵?考慮到獲取request對象的方法有微小的不同,大體可以分為兩類:

  • 在Spring的Bean中使用request對象:既包括Controller肛炮、Service止吐、Repository等MVC的Bean,也包括了Component等普通的Spring Bean侨糟。為了方便說明碍扔,后文中Spring中的Bean一律簡稱為Bean。

  • 在非Bean中使用request對象:如普通的Java對象的方法中使用秕重,或在類的靜態(tài)方法中使用不同。

此外,本文討論是圍繞代表請求的request對象展開的溶耘,但所用方法同樣適用于response對象二拐、InputStream/Reader、OutputStream/ Writer等凳兵;其中InputStream/Reader可以讀取請求中的數(shù)據(jù)百新,OutputStream/ Writer可以向響應(yīng)寫入數(shù)據(jù)。

最后留荔,獲取request對象的方法與Spring及MVC的版本也有關(guān)系吟孙;本文基于Spring4進(jìn)行討論,且所做的實(shí)驗(yàn)都是使用4.1.1版本聚蝶。

如何測試線程安全性

既然request對象的線程安全問題需要特別關(guān)注杰妓,為了便于后面的討論,下面先說明如何測試request對象是否是線程安全的碘勉。

測試的基本思路巷挥,是模擬客戶端大量并發(fā)請求,然后在服務(wù)器判斷這些請求是否使用了相同的request對象验靡。

判斷request對象是否相同倍宾,最直觀的方式是打印出request對象的地址缀台,如果相同則說明使用了相同的對象孩锡。然而粉铐,在幾乎所有web服務(wù)器的實(shí)現(xiàn)中呼猪,都使用了線程池,這樣就導(dǎo)致先后到達(dá)的兩個(gè)請求怔锌,可能由同一個(gè)線程處理:在前一個(gè)請求處理完成后寥粹,線程池收回該線程,并將該線程重新分配給了后面的請求埃元。而在同一線程中涝涤,使用的request對象很可能是同一個(gè)(地址相同,屬性不同)岛杀。因此即便是對于線程安全的方法阔拳,不同的請求使用的request對象地址也可能相同。

為了避免這個(gè)問題类嗤,一種方法是在請求處理過程中使線程休眠幾秒糊肠,這樣可以讓每個(gè)線程工作的時(shí)間足夠長,從而避免同一個(gè)線程分配給不同的請求土浸;另一種方法罪针,是使用request的其他屬性(如參數(shù)、header黄伊、body等)作為request是否線程安全的依據(jù),因?yàn)榧幢悴煌恼埱笙群笫褂昧送粋€(gè)線程(request對象地址也相同)派殷,只要使用不同的屬性分別構(gòu)造了兩次request對象还最,那么request對象的使用就是線程安全的。本文使用第二種方法進(jìn)行測試毡惜。
客戶端測試代碼如下(創(chuàng)建1000個(gè)線程分別發(fā)送請求):

public class Test {
    public static void main(String[] args) throws Exception {
        String prefix = UUID.randomUUID().toString().replaceAll("-", "") + "::";
        for (int i = 0; i < 1000; i++) {
            final String value = prefix + i;
            new Thread() {
                @Override
                public void run() {
                    try {
                        CloseableHttpClient httpClient = HttpClients.createDefault();
                        HttpGet httpGet = new HttpGet("http://localhost:8080/test?key=" + value);
                        httpClient.execute(httpGet);
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    }
}

服務(wù)器中Controller代碼如下(暫時(shí)省略了獲取request對象的代碼):

@Controller
public class TestController {
 
    // 存儲(chǔ)已有參數(shù)拓轻,用于判斷參數(shù)是否重復(fù),從而判斷線程是否安全
    public static Set<String> set = new ConcurrentSkipListSet<>();
 
    @RequestMapping("/test")
    public void test() throws InterruptedException {
         
        // …………………………通過某種方式獲得了request對象………………………………
 
        // 判斷線程安全
        String value = request.getParameter("key");
        if (set.contains(value)) {
            System.out.println(value + "\t重復(fù)出現(xiàn)经伙,request并發(fā)不安全扶叉!");
        } else {
            System.out.println(value);
            set.add(value);
        }
         
        // 模擬程序執(zhí)行了一段時(shí)間
        Thread.sleep(1000);
    }
}

補(bǔ)充:上述代碼原使用HashSet來判斷value是否重復(fù),經(jīng)網(wǎng)友批評(píng)指正帕膜,使用線程不安全的集合類驗(yàn)證線程安全性是欠妥的枣氧,現(xiàn)已改為ConcurrentSkipListSet。
如果request對象線程安全垮刹,服務(wù)器中打印結(jié)果如下所示:

image

如果存在線程安全問題达吞,服務(wù)器中打印結(jié)果可能如下所示:

image

如無特殊說明,本文后面的代碼中將省略掉測試代碼荒典。

方法1:Controller中加參數(shù)

代碼示例

@Controller
public class TestController {
    @RequestMapping("/test")
    public void test(HttpServletRequest request) throws InterruptedException {
        // 模擬程序執(zhí)行了一段時(shí)間
        Thread.sleep(1000);
    }
}

該方法實(shí)現(xiàn)的原理是酪劫,在Controller方法開始處理請求時(shí)吞鸭,Spring會(huì)將request對象賦值到方法參數(shù)中。除了request對象覆糟,可以通過這種方法獲取的參數(shù)還有很多刻剥,具體可以參見:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-methods

Controller中獲取request對象后,如果要在其他方法中(如service方法滩字、工具類方法等)使用request對象造虏,需要在調(diào)用這些方法時(shí)將request對象作為參數(shù)傳入。

線程安全性

測試結(jié)果:線程安全

分析:此時(shí)request對象是方法參數(shù)踢械,相當(dāng)于局部變量酗电,毫無疑問是線程安全的。

優(yōu)缺點(diǎn)

這種方法的主要缺點(diǎn)是request對象寫起來冗余太多内列,主要體現(xiàn)在兩點(diǎn):

  1. 如果多個(gè)controller方法中都需要request對象撵术,那么在每個(gè)方法中都需要添加一遍request參數(shù)

  2. request對象的獲取只能從controller開始,如果使用request對象的地方在函數(shù)調(diào)用層級(jí)比較深的地方话瞧,那么整個(gè)調(diào)用鏈上的所有方法都需要添加request參數(shù)

實(shí)際上嫩与,在整個(gè)請求處理的過程中,request對象是貫穿始終的交排;也就是說划滋,除了定時(shí)器等特殊情況,request對象相當(dāng)于線程內(nèi)部的一個(gè)全局變量埃篓。而該方法处坪,相當(dāng)于將這個(gè)全局變量,傳來傳去架专。

方法2:自動(dòng)注入

代碼示例

@Controller
public class TestController{
     
    @Autowired
    private HttpServletRequest request; //自動(dòng)注入request
     
    @RequestMapping("/test")
    public void test() throws InterruptedException{
        //模擬程序執(zhí)行了一段時(shí)間
        Thread.sleep(1000);
    }
}

線程安全性

測試結(jié)果:線程安全

分析:在Spring中同窘,Controller的scope是singleton(單例),也就是說在整個(gè)web系統(tǒng)中部脚,只有一個(gè)TestController想邦;但是其中注入的request卻是線程安全的,原因在于:

使用這種方式委刘,當(dāng)Bean(本例的TestController)初始化時(shí)丧没,Spring并沒有注入一個(gè)request對象,而是注入了一個(gè)代理(proxy)锡移;當(dāng)Bean中需要使用request對象時(shí)呕童,通過該代理獲取request對象。

下面通過具體的代碼對這一實(shí)現(xiàn)進(jìn)行說明罩抗。

在上述代碼中加入斷點(diǎn)拉庵,查看request對象的屬性,如下圖所示:

image

在圖中可以看出,request實(shí)際上是一個(gè)代理:代理的實(shí)現(xiàn)參見AutowireUtils的內(nèi)部類ObjectFactoryDelegatingInvocationHandler:

/**
 * Reflective InvocationHandler for lazy access to the current target object.
 */
@SuppressWarnings("serial")
private static class ObjectFactoryDelegatingInvocationHandler implements InvocationHandler, Serializable {
    private final ObjectFactory<?> objectFactory;
    public ObjectFactoryDelegatingInvocationHandler(ObjectFactory<?> objectFactory) {
        this.objectFactory = objectFactory;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // ……省略無關(guān)代碼
        try {
            return method.invoke(this.objectFactory.getObject(), args); // 代理實(shí)現(xiàn)核心代碼
        }
        catch (InvocationTargetException ex) {
            throw ex.getTargetException();
        }
    }
}

也就是說钞支,當(dāng)我們調(diào)用request的方法method時(shí)茫蛹,實(shí)際上是調(diào)用了由objectFactory.getObject()生成的對象的method方法;objectFactory.getObject()生成的對象才是真正的request對象烁挟。

繼續(xù)觀察上圖婴洼,發(fā)現(xiàn)objectFactory的類型為WebApplicationContextUtils的內(nèi)部類RequestObjectFactory;而RequestObjectFactory代碼如下:

/**
 * Factory that exposes the current request object on demand.
 */
@SuppressWarnings("serial")
private static class RequestObjectFactory implements ObjectFactory<ServletRequest>, Serializable {
    @Override
    public ServletRequest getObject() {
        return currentRequestAttributes().getRequest();
    }
    @Override
    public String toString() {
        return "Current HttpServletRequest";
    }
}

其中撼嗓,要獲得request對象需要先調(diào)用currentRequestAttributes()方法獲得RequestAttributes對象柬采,該方法的實(shí)現(xiàn)如下:

/**
 * Return the current RequestAttributes instance as ServletRequestAttributes.
 */
private static ServletRequestAttributes currentRequestAttributes() {
    RequestAttributes requestAttr = RequestContextHolder.currentRequestAttributes();
    if (!(requestAttr instanceof ServletRequestAttributes)) {
        throw new IllegalStateException("Current request is not a servlet request");
    }
    return (ServletRequestAttributes) requestAttr;
}

生成RequestAttributes對象的核心代碼在類RequestContextHolder中,其中相關(guān)代碼如下(省略了該類中的無關(guān)代碼):

public abstract class RequestContextHolder {
    public static RequestAttributes currentRequestAttributes() throws IllegalStateException {
        RequestAttributes attributes = getRequestAttributes();
        // 此處省略不相關(guān)邏輯…………
        return attributes;
    }
    public static RequestAttributes getRequestAttributes() {
        RequestAttributes attributes = requestAttributesHolder.get();
        if (attributes == null) {
            attributes = inheritableRequestAttributesHolder.get();
        }
        return attributes;
    }
    private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
            new NamedThreadLocal<RequestAttributes>("Request attributes");
    private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =
            new NamedInheritableThreadLocal<RequestAttributes>("Request context");
}

通過這段代碼可以看出且警,生成的RequestAttributes對象是線程局部變量(ThreadLocal)粉捻,因此request對象也是線程局部變量;這就保證了request對象的線程安全性斑芜。

優(yōu)缺點(diǎn)

該方法的主要優(yōu)點(diǎn):

  1. 注入不局限于Controller中:在方法1中肩刃,只能在Controller中加入request參數(shù)。而對于方法2杏头,不僅可以在Controller中注入盈包,還可以在任何Bean中注入,包括Service醇王、Repository及普通的Bean呢燥。

  2. 注入的對象不限于request:除了注入request對象,該方法還可以注入其他scope為request或session的對象寓娩,如response對象叛氨、session對象等;并保證線程安全棘伴。

  3. 減少代碼冗余:只需要在需要request對象的Bean中注入request對象力试,便可以在該Bean的各個(gè)方法中使用,與方法1相比大大減少了代碼冗余排嫌。

但是,該方法也會(huì)存在代碼冗余缰犁〈镜兀考慮這樣的場景:web系統(tǒng)中有很多controller,每個(gè)controller中都會(huì)使用request對象(這種場景實(shí)際上非常頻繁)帅容,這時(shí)就需要寫很多次注入request的代碼颇象;如果還需要注入response,代碼就更繁瑣了并徘。下面說明自動(dòng)注入方法的改進(jìn)方法遣钳,并分析其線程安全性及優(yōu)缺點(diǎn)。

方法3:基類中自動(dòng)注入

代碼示例

與方法2相比麦乞,將注入部分代碼放入到了基類中蕴茴。

  • 基類代碼:
public class BaseController {
    @Autowired
    protected HttpServletRequest request;     
}

Controller代碼如下劝评;這里列舉了BaseController的兩個(gè)派生類,由于此時(shí)測試代碼會(huì)有所不同倦淀,因此服務(wù)端測試代碼沒有省略蒋畜;客戶端也需要進(jìn)行相應(yīng)的修改(同時(shí)向2個(gè)url發(fā)送大量并發(fā)請求)。

@Controller
public class TestController extends BaseController {
 
    // 存儲(chǔ)已有參數(shù)撞叽,用于判斷參數(shù)value是否重復(fù)姻成,從而判斷線程是否安全
    public static Set<String> set = new ConcurrentSkipListSet<>();
 
    @RequestMapping("/test")
    public void test() throws InterruptedException {
        String value = request.getParameter("key");
        // 判斷線程安全
        if (set.contains(value)) {
            System.out.println(value + "\t重復(fù)出現(xiàn),request并發(fā)不安全愿棋!");
        } else {
            System.out.println(value);
            set.add(value);
        }
        // 模擬程序執(zhí)行了一段時(shí)間
        Thread.sleep(1000);
    }
}

@Controller
public class Test2Controller extends BaseController {
    @RequestMapping("/test2")
    public void test2() throws InterruptedException {
        String value = request.getParameter("key");
        // 判斷線程安全(與TestController使用一個(gè)set進(jìn)行判斷)
        if (TestController.set.contains(value)) {
            System.out.println(value + "\t重復(fù)出現(xiàn)科展,request并發(fā)不安全!");
        } else {
            System.out.println(value);
            TestController.set.add(value);
        }
        // 模擬程序執(zhí)行了一段時(shí)間
        Thread.sleep(1000);
    }
}

線程安全性

測試結(jié)果:線程安全

分析:在理解了方法2的線程安全性的基礎(chǔ)上糠雨,很容易理解方法3是線程安全的:當(dāng)創(chuàng)建不同的派生類對象時(shí)才睹,基類中的域(這里是注入的request)在不同的派生類對象中會(huì)占據(jù)不同的內(nèi)存空間,也就是說將注入request的代碼放在基類中對線程安全性沒有任何影響见秤;測試結(jié)果也證明了這一點(diǎn)砂竖。

優(yōu)缺點(diǎn)

與方法2相比,避免了在不同的Controller中重復(fù)注入request鹃答;但是考慮到j(luò)ava只允許繼承一個(gè)基類乎澄,所以如果Controller需要繼承其他類時(shí),該方法便不再好用测摔。

無論是方法2和方法3置济,都只能在Bean中注入request;如果其他方法(如工具類中static方法)需要使用request對象锋八,則需要在調(diào)用這些方法時(shí)將request參數(shù)傳遞進(jìn)去浙于。下面介紹的方法4,則可以直接在諸如工具類中的static方法中使用request對象(當(dāng)然在各種Bean中也可以使用)挟纱。

方法4:手動(dòng)調(diào)用

代碼示例

@Controller
public class TestController {
    @RequestMapping("/test")
    public void test() throws InterruptedException {
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        // 模擬程序執(zhí)行了一段時(shí)間
        Thread.sleep(1000);
    }
}

線程安全性

測試結(jié)果:線程安全

分析:該方法與方法2(自動(dòng)注入)類似羞酗,只不過方法2中通過自動(dòng)注入實(shí)現(xiàn),本方法通過手動(dòng)方法調(diào)用實(shí)現(xiàn)紊服。因此本方法也是線程安全的檀轨。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):可以在非Bean中直接獲取。缺點(diǎn):如果使用的地方較多欺嗤,代碼非常繁瑣参萄;因此可以與其他方法配合使用。

方法5:@ModelAttribute方法

代碼示例

下面這種方法及其變種(變種:將request和bindRequest放在子類中)在網(wǎng)上經(jīng)常見到:

@Controller
public class TestController {
    private HttpServletRequest request;
    @ModelAttribute
    public void bindRequest(HttpServletRequest request) {
        this.request = request;
    }
    @RequestMapping("/test")
    public void test() throws InterruptedException {
        // 模擬程序執(zhí)行了一段時(shí)間
        Thread.sleep(1000);
    }
}

線程安全性

測試結(jié)果:線程不安全

分析:@ModelAttribute注解用在Controller中修飾方法時(shí)煎饼,其作用是Controller中的每個(gè)@RequestMapping方法執(zhí)行前讹挎,該方法都會(huì)執(zhí)行。因此在本例中,bindRequest()的作用是在test()執(zhí)行前為request對象賦值筒溃。雖然bindRequest()中的參數(shù)request本身是線程安全的马篮,但由于TestController是單例的,request作為TestController的一個(gè)域铡羡,無法保證線程安全积蔚。

總結(jié)

綜上所述,Controller中加參數(shù)(方法1)烦周、自動(dòng)注入(方法2和方法3)尽爆、手動(dòng)調(diào)用(方法4)都是線程安全的,都可以用來獲取request對象读慎。如果系統(tǒng)中request對象使用較少漱贱,則使用哪種方式均可;如果使用較多夭委,建議使用自動(dòng)注入(方法2 和方法3)來減少代碼冗余幅狮。如果需要在非Bean中使用request對象,既可以在上層調(diào)用時(shí)通過參數(shù)傳入株灸,也可以直接在方法中通過手動(dòng)調(diào)用(方法4)獲得崇摄。

此外,本文在討論獲取request對象的方法時(shí)慌烧,重點(diǎn)討論該方法的線程安全性逐抑、代碼的繁瑣程度等;在實(shí)際的開發(fā)過程中屹蚊,還必須考慮所在項(xiàng)目的規(guī)范厕氨、代碼維護(hù)等問題(此處感謝網(wǎng)友的批評(píng)指正)。

參考文獻(xiàn)

https://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other-injection

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-methods

https://stackoverflow.com/questions/10541934/spring-aop-and-aspect-thread-safety-for-an-autowired-httpservletrequest-bean

http://www.phpchina.com/portal.php?mod=view&aid=40966

https://stackoverflow.com/questions/22674044/inject-httpservletrequest-into-controller

https://stackoverflow.com/questions/3320674/spring-how-do-i-inject-an-httpservletrequest-into-a-request-scoped-bean

https://my.oschina.net/sluggarddd/blog/678603?fromerr=XhvpvVTi

https://stackoverflow.com/questions/8504258/spring-3-mvc-accessing-httprequest-from-controller


文章摘自:http://www.cnblogs.com/kismetv/p/8757260.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汹粤,一起剝皮案震驚了整個(gè)濱河市命斧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嘱兼,老刑警劉巖国葬,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芹壕,居然都是意外死亡胃惜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門哪雕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鲫趁,你說我怎么就攤上這事斯嚎。” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵堡僻,是天一觀的道長糠惫。 經(jīng)常有香客問我,道長钉疫,這世上最難降的妖魔是什么硼讽? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮牲阁,結(jié)果婚禮上固阁,老公的妹妹穿的比我還像新娘。我一直安慰自己城菊,他們只是感情好备燃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凌唬,像睡著了一般并齐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上客税,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天况褪,我揣著相機(jī)與錄音,去河邊找鬼更耻。 笑死测垛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的酥夭。 我是一名探鬼主播赐纱,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼熬北!你這毒婦竟也來了疙描?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤讶隐,失蹤者是張志新(化名)和其女友劉穎起胰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巫延,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡效五,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了炉峰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畏妖。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖疼阔,靈堂內(nèi)的尸體忽然破棺而出戒劫,到底是詐尸還是另有隱情半夷,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布迅细,位于F島的核電站巫橄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏茵典。R本人自食惡果不足惜湘换,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望统阿。 院中可真熱鬧彩倚,春花似錦、人聲如沸砂吞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜻直。三九已至盯质,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間概而,已是汗流浹背呼巷。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赎瑰,地道東北人王悍。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像餐曼,于是被迫代替她去往敵國和親压储。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理源譬,服務(wù)發(fā)現(xiàn)集惋,斷路器,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • 1.1 spring IoC容器和beans的簡介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器踩娘,...
    simoscode閱讀 6,714評(píng)論 2 22
  • 我對作業(yè)是非常頭疼的刮刑,雖然我的作業(yè)一般都會(huì)完成,我認(rèn)為不完成作業(yè)是一個(gè)不好的現(xiàn)象养渴,在這個(gè)暑假這么多天里雷绢,我依然在完...
    百合花張馨文閱讀 245評(píng)論 0 1
  • 第二次的東京,少了幾分走馬觀花的新奇理卑,多了幾分踏踏實(shí)實(shí)的滿足翘紊。 1. 與花火大會(huì)擦肩而過。 2.宮崎駿藐唠,我們都曾經(jīng)...
    柚子琥珀閱讀 299評(píng)論 1 0
  • 2017年4月6日 星期四 天氣陰 今天練背霞溪,一切按步就班孵滞。最后的跑步堅(jiān)持了16分鐘。還是那個(gè)教練說看我的臉已經(jīng)瘦...
    whatcanhumando閱讀 84評(píng)論 0 0