Spring定時(shí)器的配置從1.0到5.0的演進(jìn)

這里主要是記錄下從Spring1.0到現(xiàn)在的5.0中定時(shí)器的配置方式桶癣,關(guān)于源碼,暫先不解釋。主要用作自己記錄用今野,如果有錯(cuò)誤的還請(qǐng)指出一起改正學(xué)習(xí)葡公,免得誤導(dǎo)別人,謝謝条霜。

Spring1中定時(shí)器的配置

直接看Spring1.1.1的文檔催什,里面都已經(jīng)給出來了各種配置方式,更高版本的也都包含了這些宰睡,但是覺得看1.1.1的更純粹一些蒲凶。

Spring1中對(duì)定時(shí)器的支持有兩種方式:

  • jdk的Timer
  • Quartz Scheduler

Quartz Scheduler

Quartz Scheduler使用Triggers,Jobs拆内,JobDetail來實(shí)現(xiàn)定時(shí)器功能旋圆。Spring提供了對(duì)Quartz的支持。

使用的大概步驟是:

  1. 定義JobDetail矛纹,也就是定義具體的任務(wù)臂聋。
  2. 定義trigger,就是定義觸發(fā)器或南,指定什么任務(wù)孩等,在什么時(shí)間執(zhí)行或者隔多久執(zhí)行。
  3. 定義SchedulerFactoryBean采够,來執(zhí)行任務(wù)肄方。

下面我們以一個(gè)例子來說明,是一個(gè)定時(shí)的去獲取信息和定時(shí)統(tǒng)計(jì)信息的示例蹬癌。

定義JobDetail

定義JobDetail有兩種方式权她,一種是使用JobDetailBean,一種是使用MethodInvokingJobDetailFactoryBean逝薪,后者可以指定要執(zhí)行的具體方法隅要。

使用JobDetailBean

CountUserJob:

package me.cxis.spring.scheduling.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * Created by cheng.xi on 2017-04-19 11:00.
 * 定時(shí)的統(tǒng)計(jì)信息的JOb
 * 比如這里是定時(shí)的統(tǒng)計(jì)系統(tǒng)中總的用戶數(shù),總的用戶數(shù)是我查詢到的數(shù)和我在xml指定的數(shù)的總和
 */
public class CountUserJob extends QuartzJobBean{

    private int adminUser;

    public void setAdminUser(int adminUser) {
        this.adminUser = adminUser;
    }

    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        //執(zhí)行真正的統(tǒng)計(jì)任務(wù)
        System.out.println("開始統(tǒng)計(jì)系統(tǒng)中人數(shù)");
        System.out.println("統(tǒng)計(jì)完成董济,共有101人");
        System.out.println("加上系統(tǒng)管理員之后共有" + (adminUser + 101) + "人");
    }
}

xml中聲明一個(gè)job:

<!--定義一個(gè)JobDetailBean類型的Job步清,用來統(tǒng)計(jì)系統(tǒng)中總的人數(shù),adminUser指的是系統(tǒng)中預(yù)先留的管理員數(shù)目-->
<bean name="countUserJob" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass">
        <value>me.cxis.spring.scheduling.quartz.CountUserJob</value>
    </property>
    <property name="jobDataAsMap">
        <map>
            <entry key="adminUser">
                <value>10</value>
            </entry>
        </map>
    </property>
</bean>

使用MethodInvokingJobDetailFactoryBean

MethodInvokingJobDetailFactoryBean可以指定方法虏肾。直接看例子廓啊。

GetJob:

package me.cxis.spring.scheduling.quartz;

/**
 * Created by cheng.xi on 2017-04-19 11:01.
 * 定時(shí)的獲取信息的Job,定時(shí)從文件中獲取數(shù)據(jù)
 */
public class GetJob {
    public void getSomethingFromFile(){
        System.out.println("從文件中獲取數(shù)據(jù)封豪。谴轮。。吹埠。");
    }
}

xml中配置:

<!--從文件中獲取信息的bean-->
<bean id="getJob" class="me.cxis.spring.scheduling.quartz.GetJob"/>

<!--定義一個(gè)MethodInvokingJobDetailFactoryBean第步,從文件中獲取數(shù)據(jù)的Job-->
<bean id="getJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject"><ref bean="getJob"/></property>
    <property name="targetMethod"><value>getSomethingFromFile</value></property>
</bean>

定義Triggers

上面我們把JobDetail都定義好了疮装,也都配置好了,但是怎么去執(zhí)行雌续,多長(zhǎng)時(shí)間執(zhí)行一次都沒有說明斩个,這時(shí)候需要定義Triggers來描述任務(wù)什么時(shí)候執(zhí)行等。只需要在xml中配置就可以了驯杜。

Triggers也有兩種方式受啥,一種是SimpleTriggerBean,一種是CronTriggerBean鸽心。我們的例子中滚局,統(tǒng)計(jì)用戶數(shù)使用SimpleTriggerBean,從文件中獲取信息使用CronTriggerBean顽频。

<!--定義Triggers藤肢,統(tǒng)計(jì)用戶數(shù)-->
<bean id="countUserTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail">
        <ref bean="countUserJob"/>
    </property>
    <!--第一次執(zhí)行之前需要等待的時(shí)間-->
    <property name="startDelay">
        <!--10秒-->
        <value>10000</value>
    </property>
    <!--任務(wù)重復(fù)時(shí)間,每隔多少時(shí)間執(zhí)行一次-->
    <property name="repeatInterval">
        <value>20000</value>
    </property>
</bean>

<!--定義Triggers糯景,定時(shí)從文件中獲取數(shù)據(jù)-->
<bean id="getJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail">
        <ref bean="getJobDetail"/>
    </property>
    <property name="cronExpression">
        <!--cron表達(dá)式嘁圈,這里是每隔兩分鐘執(zhí)行一次-->
        <value>0 0/2 * * * ?</value>
    </property>
</bean>

定義SchedulerFactoryBean

<!--定義SchedulerFactoryBean-->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref local="countUserTrigger"/>
            <ref local="getJobTrigger"/>
        </list>
    </property>
</bean>

測(cè)試

Main:

package me.cxis.spring.scheduling.quartz;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by cheng.xi on 2017-04-19 11:34.
 */
public class Main {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:scheduling-quartz.xml");
    }
}

JDK Timer

使用JDK Timer,也跟上面類似蟀淮,大概的步驟是:

  1. 創(chuàng)建一個(gè)TimerTask最住,里面是執(zhí)行任務(wù)的邏輯。
  2. 創(chuàng)建ScheduledTimerTask怠惶,就是什么時(shí)候或者隔多久執(zhí)行任務(wù)涨缚。
  3. 創(chuàng)建TimerFactoryBean,來執(zhí)行任務(wù)策治。

創(chuàng)建TimerTask

同樣脓魏,創(chuàng)建一個(gè)Task也有兩種方式,一種是繼承TimerTask通惫,另外一種是使用MethodInvokingTimerTaskFactoryBean茂翔,后者可以指定具體方法。

繼承TimerTask

CountUserTask:

package me.cxis.spring.scheduling.timer;

import java.util.TimerTask;

/**
 * Created by cheng.xi on 2017-04-19 11:00.
 * 定時(shí)的統(tǒng)計(jì)信息的 task
 * 比如這里是定時(shí)的統(tǒng)計(jì)系統(tǒng)中總的用戶數(shù)履腋,總的用戶數(shù)是我查詢到的數(shù)和我在xml指定的數(shù)的總和
 */
public class CountUserTask extends TimerTask{

    private int adminUser;

    public void setAdminUser(int adminUser) {
        this.adminUser = adminUser;
    }

    public void run() {
        //執(zhí)行真正的統(tǒng)計(jì)任務(wù)
        System.out.println("開始統(tǒng)計(jì)系統(tǒng)中人數(shù)");
        System.out.println("統(tǒng)計(jì)完成檩电,共有101人");
        System.out.println("加上系統(tǒng)管理員之后共有" + (adminUser + 101) + "人");
    }
}

在xml中配置bean:

<!--統(tǒng)計(jì)用戶數(shù)的bean-->
<bean id="countUserTask" class="me.cxis.spring.scheduling.timer.CountUserTask">
    <property name="adminUser">
        <value>10</value>
    </property>
</bean>

使用MethodInvokingTimerTaskFactoryBean

GetTask:

package me.cxis.spring.scheduling.timer;

/**
 * Created by cheng.xi on 2017-04-19 11:01.
 * 定時(shí)的獲取信息的task,定時(shí)從文件中獲取數(shù)據(jù)
 */
public class GetTask {
    public void getSomethingFromFile(){
        System.out.println("從文件中獲取數(shù)據(jù)府树。。料按。奄侠。");
    }
}

xml中配置:

<!--從文件中獲取信息的bean-->
<bean id="getTaskBean" class="me.cxis.spring.scheduling.timer.GetTask"></bean>

<!--使用MethodInvokingTimerTaskFactoryBean-->
<bean id="getTask" class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
    <property name="targetObject"><ref bean="getTaskBean"/> </property>
    <property name="targetMethod"><value>getSomethingFromFile</value></property>
</bean>

創(chuàng)建ScheduledTimerTask

定義ScheduledTimerTask來描述任務(wù)什么時(shí)候執(zhí)行等。只需要在xml中配置就可以了载矿。

使用Timer的方式垄潮,就這么一種配置烹卒,沒法使用cron的方式。

<!--創(chuàng)建統(tǒng)計(jì)用戶的ScheduledTimerTask弯洗,描述任務(wù)怎么運(yùn)行-->
<bean id="countUserScheduledTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
    <property name="delay">
        <value>10000</value>
    </property>
    <property name="period">
        <value>20000</value>
    </property>
    <property name="timerTask">
        <ref local="countUserTask"/>
    </property>
</bean>

<!--創(chuàng)建從文件獲取信息的ScheduledTimerTask旅急,描述任務(wù)怎么運(yùn)行-->
<bean id="getScheduledTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
    <property name="period">
        <value>60000</value>
    </property>
    <property name="timerTask">
        <ref local="getTask"/>
    </property>
</bean>

創(chuàng)建TimerFactoryBean

任務(wù)執(zhí)行的配置:

<!--創(chuàng)建TimerFactoryBean,執(zhí)行任務(wù)-->
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
    <property name="scheduledTimerTasks">
        <list>
            <ref local="countUserScheduledTimerTask"/>
            <ref local="getScheduledTimerTask"/>
        </list>
    </property>
</bean>

測(cè)試

package me.cxis.spring.scheduling.timer;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;
import java.io.InputStream;

/**
 * Created by cheng.xi on 2017-04-19 11:34.
 */
public class Main {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:scheduling-timer.xml");
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上面就是Spring1.x中關(guān)于定時(shí)器的配置方式牡整,配置清晰藐吮,易懂,但是任務(wù)多了之后逃贝,就會(huì)發(fā)現(xiàn)配置文件會(huì)迅速變得臃腫谣辞。

Spring2中定時(shí)器的配置

What's new in Spring 2.0?

  • 增加對(duì)Executors的支持

上面就是AOP在2.0版本新增的特性,1.0的所有AOP配置方式在2.0中都支持沐扳,下面主要看看2.0中新增的一些方法泥从。

Spring2.0中新定義了一個(gè)TaskExecutor接口,增加了對(duì)線程池的支持沪摄,這個(gè)接口的功能跟JDK1.5中的Executor接口一樣躯嫉。那么2.0中線程池的增加,對(duì)定時(shí)器有什么影響呢杨拐?其實(shí)就是可以在定時(shí)任務(wù)執(zhí)行的時(shí)候祈餐,使用線程池來執(zhí)行任務(wù),我們不用關(guān)心其他的實(shí)現(xiàn)戏阅。

Spring2中配置示例

直接看示例昼弟,我們定時(shí),每隔5分鐘奕筐,每次都從20個(gè)文件中同時(shí)獲取數(shù)據(jù)舱痘。

首先寫實(shí)際執(zhí)行業(yè)務(wù)的類,

package me.cxis.spring.scheduling.executor;

/**
 * Created by cheng.xi on 2017-04-19 14:51.
 * 從文件中獲取數(shù)據(jù)的Task
 */
public class GetDataFromFileTask implements Runnable {

    private int fileId;

    public GetDataFromFileTask(int fileId){
        this.fileId = fileId;
    }

    public void run() {
        //真正執(zhí)行從文件中獲取數(shù)據(jù)的邏輯
        System.out.println("從文件" + fileId + "中獲取數(shù)據(jù)");
    }
}

然后是執(zhí)行任務(wù)的定時(shí)器:

package me.cxis.spring.scheduling.executor;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.TimerTask;

/**
 * Created by cheng.xi on 2017-04-19 14:54.
 * 批量從文件中獲取數(shù)據(jù)的定時(shí)器
 */
public class GetDataFromFileScheduler extends TimerTask {

    private ThreadPoolTaskExecutor executor;

    public void setExecutor(ThreadPoolTaskExecutor executor) {
        this.executor = executor;
    }

    public void run() {
        System.out.println("CorePoolSize:" + taskExecutor.getCorePoolSize() + ";MaxPoolSize:" + taskExecutor.getMaxPoolSize());
        //每次都會(huì)同時(shí)執(zhí)行從20個(gè)文件中獲取數(shù)據(jù)
        for(int i = 0; i < 20;i++){
            executor.execute(new GetDataFromFileTask(i));
        }
    }
}

接著是xml的配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <!--線程池taskExecutor-->
    <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!--核心線程數(shù)-->
        <property name="corePoolSize">
            <value>5</value>
        </property>
        <!--最大線程數(shù)-->
        <property name="maxPoolSize">
            <value>10</value>
        </property>
        <!--隊(duì)列最大長(zhǎng)度-->
        <property name="queueCapacity">
            <value>40</value>
        </property>
    </bean>

    <!--GetDataFromFileScheduler离赫,獲取數(shù)據(jù)的定時(shí)器-->
    <bean id="getDataFromFileScheduler" class="me.cxis.spring.scheduling.executor.GetDataFromFileScheduler">
        <property name="taskExecutor">
            <ref local="taskExecutor"/>
        </property>
    </bean>

    <!--創(chuàng)建統(tǒng)計(jì)用戶的ScheduledTimerTask芭逝,描述任務(wù)怎么運(yùn)行-->
    <bean id="getDataFromFileTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
        <property name="delay">
            <value>10000</value>
        </property>
        <property name="period">
            <value>20000</value>
        </property>
        <property name="timerTask">
            <ref local="getDataFromFileScheduler"/>
        </property>
    </bean>

    <!--創(chuàng)建TimerFactoryBean,執(zhí)行任務(wù)-->
    <bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
        <property name="scheduledTimerTasks">
            <list>
                <ref local="getDataFromFileTimerTask"/>
            </list>
        </property>
    </bean>

</beans>

測(cè)試類:

package me.cxis.spring.scheduling.executor;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by cheng.xi on 2017-04-19 15:11.
 */
public class Main {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:scheduling-executor.xml");
    }
}

上面就是結(jié)合線程池的示例渊胸。也就是在執(zhí)行任務(wù)的時(shí)候多了線程池旬盯,基本的配置方式使用方法基本沒變。

Spring3中定時(shí)器的配置

  • Spring3中TaskExecutor繼承了JDK的Executor翎猛。使用方面還是跟原來2.0一樣胖翰。
  • Spring3中還引入了新的接口TaskScheduler,Trigger切厘,TriggerContext等萨咳。
  • Spring3中還引入了task的命名空間<task:scheduler/><task:executor/>疫稿,<task:scheduled-tasks/>等培他。
  • Spring3中還支持注解的方式@Scheduled鹃两,@Async,使配置更加簡(jiǎn)化舀凛。使用注解的方式俊扳,需要在配置文件中先開啟注解支持<task:annotation-driven/>

注解方式的示例如下。

CountUserTask:

package me.cxis.spring.scheduling.annotation;


import org.springframework.scheduling.annotation.Scheduled;

/**
 * Created by cheng.xi on 2017-04-19 11:00.
 * 定時(shí)的統(tǒng)計(jì)信息的Task
 *
 */
public class CountUserTask{

    //@Scheduled(cron="*/5 * * * * MON-FRI") cron的方式
    //下面是固定時(shí)間猛遍,每隔5秒執(zhí)行一次
    @Scheduled(fixedRate = 5000)
    public void countUser(){
        //執(zhí)行真正的統(tǒng)計(jì)任務(wù)
        System.out.println("開始統(tǒng)計(jì)系統(tǒng)中人數(shù)");
        System.out.println("統(tǒng)計(jì)完成馋记,共有101人");
    }
}

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

    <!--開啟task的注解支持-->
    <task:annotation-driven />

    <!--執(zhí)行任務(wù)的bean-->
    <bean id="countUserTask" class="me.cxis.spring.scheduling.annotation.CountUserTask"/>
</beans>

測(cè)試:

package me.cxis.spring.scheduling.annotation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * Created by cheng.xi on 2017-04-19 16:08.
 */
public class Main {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:scheduling-annotation.xml");
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

可以看到,使用注解的方式簡(jiǎn)化了很多很多螃壤。

Spring4和Spring5中定時(shí)器的配置

Spring4中增加了@EnableScheduling注解來啟用對(duì)@Scheduled注解的支持抗果。其他的基本沒有什么變化,使用方式還是跟以前一樣奸晴,現(xiàn)在使用注解更多冤馏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市寄啼,隨后出現(xiàn)的幾起案子逮光,更是在濱河造成了極大的恐慌,老刑警劉巖墩划,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涕刚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡乙帮,警方通過查閱死者的電腦和手機(jī)杜漠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來察净,“玉大人驾茴,你說我怎么就攤上這事∏饪ǎ” “怎么了锈至?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)译秦。 經(jīng)常有香客問我峡捡,道長(zhǎng),這世上最難降的妖魔是什么筑悴? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任们拙,我火速辦了婚禮,結(jié)果婚禮上阁吝,老公的妹妹穿的比我還像新娘睛竣。我一直安慰自己,他們只是感情好求摇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布射沟。 她就那樣靜靜地躺著,像睡著了一般与境。 火紅的嫁衣襯著肌膚如雪验夯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天摔刁,我揣著相機(jī)與錄音挥转,去河邊找鬼。 笑死共屈,一個(gè)胖子當(dāng)著我的面吹牛绑谣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拗引,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼借宵,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了矾削?” 一聲冷哼從身側(cè)響起壤玫,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哼凯,沒想到半個(gè)月后欲间,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡断部,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年猎贴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝴光。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡她渴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出虱疏,到底是詐尸還是另有隱情惹骂,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布做瞪,位于F島的核電站对粪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏装蓬。R本人自食惡果不足惜著拭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望牍帚。 院中可真熱鬧儡遮,春花似錦、人聲如沸暗赶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至十嘿,卻和暖如春因惭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绩衷。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工蹦魔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咳燕。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓勿决,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親招盲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子低缩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)宪肖,斷路器表制,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,806評(píng)論 6 342
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,085評(píng)論 25 707
  • 隨著中秋節(jié)的逼近,節(jié)日的氣氛愈加濃厚控乾。 瞧~ 發(fā)單人員手上拿著的活動(dòng)宣傳單么介; 超市里掛著的彩帶、氣球蜕衡; 貨物架上擺...
    芙蓉出水閱讀 211評(píng)論 1 4
  • 來我的城吧壤短,讓我看看你的樣子,她輕輕說慨仿。 幾乎是帶著朝圣的心情久脯,他踏上征程。一個(gè)人若心無歸依镰吆,那么靈魂...
    雨夜剪燭閱讀 344評(píng)論 3 10