springboot3筆記第二章掌控springboot基礎(chǔ)篇

動(dòng)力節(jié)點(diǎn)王鶴springboot3視頻筆記第二章

2.掌控SpringBoot基礎(chǔ)篇

2.1 Spring Boot ?

Spring Boot 是目前流行的微服務(wù)框架 倡導(dǎo) 約定優(yōu)先于配置” 其設(shè) 目的是 用來簡化新 Spring 應(yīng)用的初始化搭建以及開發(fā)過程枕赵。 Spring Boot 提供了很多核心的功 能,比如自動(dòng)化配置 starter(啟動(dòng)器) 簡化 Maven 配置、內(nèi)嵌 Servlet 容器警检、應(yīng)用監(jiān)控等功能茅撞, 讓我們可以快速構(gòu)建企業(yè)級(jí)應(yīng)用程序堵未。

特性:1.創(chuàng)建獨(dú)立的Spring 應(yīng)用程序栅隐。2.嵌入式 Tomcat辉懒、 Jetty清女、 Undertow容器(jar)3.提供的 starters 簡化構(gòu)建配置(簡化依賴管理和版本控制)4.盡可能自動(dòng)配置 spring應(yīng)用和第三方庫5.提供生產(chǎn)指標(biāo),例如指標(biāo)钱烟、健壯檢查和外部化配置6.沒有代碼生成,無需XML配置

SpringBoot同時(shí)提供“開箱即用”嫡丙,“約定優(yōu)于配置”的特性拴袭。

開箱即用:Spring Boot應(yīng)用無需從0開始,使用腳手架創(chuàng)建項(xiàng)目曙博〉狙铮基礎(chǔ)配置已經(jīng)完成。 集成大部分第三方庫對(duì)象羊瘩,無需配置就能使用泰佳。例如在Spring Boot項(xiàng)目中使用MyBatis〕韭穑可以直接使用XXXMapper對(duì)象逝她, 調(diào)用方法執(zhí)行sql語句。約定優(yōu)于配置:Spring Boot定義了常用類睬捶,包的位置和結(jié)構(gòu)黔宛,默認(rèn)的設(shè)置。代碼不需要做調(diào)整擒贸,項(xiàng)目能夠按照預(yù)期運(yùn)行臀晃。比如啟動(dòng)類在根包的路徑下,使用了@SpringBooApplication注解介劫。 創(chuàng)建了默認(rèn)的測(cè)試類徽惋。controller, service座韵,dao應(yīng)該放在根包的子包中险绘。application為默認(rèn)的配置文件踢京。腳手架(spring提供的一個(gè)web應(yīng)用,幫助開發(fā)人員宦棺,創(chuàng)建springboot項(xiàng)目)SpringBoot3 最小jdk17瓣距, 支持17-20.

Spring Boot理念“約定優(yōu)于配置”,也可稱為按約定編程

2.1.1 與Spring關(guān)系

Spring框架:Spring Boot創(chuàng)建的是Spring應(yīng)用代咸,對(duì)于這點(diǎn)非常重要蹈丸。也就是使用Spring框架創(chuàng)建的應(yīng)用程序。這里的Spring是指 Spring Framework呐芥。 我們常說的Spring白华,一般指Spring家族,包括Spring Boot贩耐、Spring Framework 、Spring Data 厦取,Spring Security,Spring Batch , Spring Shell, Spring for Apache Kafka ....潮太。

2004年3月,Spring Framework1.0發(fā)布虾攻。2006年10 月铡买,Spring Framework2.0發(fā)布。2006年后開始霎箍,國內(nèi)項(xiàng)目漸漸的開始應(yīng)用Spring框架奇钞,2009年12月,Spring3.0發(fā)布漂坏。這時(shí)國內(nèi)已經(jīng)比較注重Spring使用了景埃。項(xiàng)目多數(shù)轉(zhuǎn)移到Spring框架了。 我是在2007開始知道漸漸了解Spring框架顶别。 那個(gè)時(shí)候用Struts或者就是jsp+servlet+jdbc比較多谷徙。當(dāng)時(shí)研發(fā)項(xiàng)目也沒什么煩惱, 就一驯绎,兩個(gè)技術(shù)可以用完慧。沒什么可選擇的。現(xiàn)在的框架剩失,技術(shù)太多了屈尼。2017 年 09 月,Spring Framework5.0 發(fā)布拴孤。 2022年11月Spring Framework6.0發(fā)布脾歧。第一個(gè)版本1.0的blog:https://spring.io/blog/2004/03/24/spring-framework-1-0-final-released

Spring的核心功能:IoC , AOP , 事務(wù)管理,JDBC演熟,SpringMVC 涨椒, Spring WebFlux,集成第三方框架MyBatis,Hibernate, Kafka , 消息隊(duì)列...Spring包含SpringMVC, SpringMVC作為web開發(fā)的強(qiáng)有力框架,是Spring中的一個(gè)模塊蚕冬。

首先明確一點(diǎn)免猾,Spring Boot和Spring Framework都是創(chuàng)建的Spring應(yīng)用程序。Spring Boot 是一個(gè)新的框架囤热,看做是Spring 框架的擴(kuò)展猎提,它消除了設(shè)置 Spring 應(yīng)用程序所需的 XML配置,為更快旁蔼,更高效的創(chuàng)建Spring應(yīng)用提供了基礎(chǔ)平臺(tái)锨苏。Spring Boot能夠快速創(chuàng)建基于Spring ,SpringMVC的普通應(yīng)用以及Web項(xiàng)目棺聊。

SpringBoot是包含了Spring 伞租、SpringMVC的高級(jí)的框架,提供了自動(dòng)功能限佩,短平快葵诈。能夠更快的創(chuàng)建Spring應(yīng)用。消除了Spring的XML配置文件祟同,提供了開發(fā)效率作喘,消除Spring應(yīng)用的臃腫。避免了大量的樣板代碼晕城。

所以學(xué)習(xí)Spring Boot的建議:了解Spring + SpringMVC核心功能泞坦,基本應(yīng)用是最好的,能夠更快的上手Spring Boot砖顷。一般的Spring Boot課程中默認(rèn)聽眾是會(huì)Spring 贰锁,SpringMVC的。


Spring Boot在現(xiàn)在Java開發(fā)人員必須掌握的框架滤蝠。Spring Boot是掌握Spring Cloud的基礎(chǔ)李根。

2.1.2 與SpringCloud關(guān)系

微服務(wù):微服務(wù)(Microservices Architecture)是一種架構(gòu)和組織方法,微服務(wù)是指單個(gè)小型的但有業(yè)務(wù)功能的服務(wù)几睛,每個(gè)服務(wù)都有自己的處理和輕量通訊機(jī)制房轿,可以部署在單個(gè)或多個(gè)服務(wù)器上。

將一個(gè)大型應(yīng)用的功能所森,依據(jù)業(yè)務(wù)功能類型囱持,抽象出相對(duì)獨(dú)立的功能,稱為服務(wù)焕济。每個(gè)服務(wù)就上一個(gè)應(yīng)用程序纷妆,有自己的業(yè)務(wù)功能,通過輕量級(jí)的通信機(jī)制與其他服務(wù)通信(通常是基于HTTP的RESTful API)晴弃,協(xié)調(diào)其他服務(wù)完成業(yè)務(wù)請(qǐng)求的處理掩幢。 這樣的服務(wù)是獨(dú)立的逊拍,與其他服務(wù)是隔離的, 可以獨(dú)立部署际邻,運(yùn)行芯丧。與其他服務(wù)解耦合。

微服務(wù)看做是模塊化的應(yīng)用世曾,將一個(gè)大型應(yīng)用缨恒,分成多個(gè)獨(dú)立的服務(wù),通過http或rpc將多個(gè)部分聯(lián)系起來轮听。請(qǐng)求沿著一定的請(qǐng)求路徑骗露,完成服務(wù)處理。

項(xiàng)目規(guī)模大血巍,服務(wù)多萧锉。要構(gòu)建大型的分布式應(yīng)用,保證應(yīng)用的穩(wěn)定述寡,高效柿隙,不間斷的提供服務(wù)。Spring Cloud是對(duì)分布式項(xiàng)目提供了辨赐,有力的支持。Spring Cloud是一系列框架的有序的組合京办,為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中常用工具(例如,配置管理、服務(wù)發(fā)現(xiàn)坡疼、斷路器歌憨、智能路由、微代理财饥、控制總線换吧、一次性令牌、全局鎖钥星、領(lǐng)導(dǎo)選舉沾瓦、分布式會(huì)話、集群狀態(tài))谦炒。開發(fā)人員使用使用Spring Cloud這套框架和工具的集合可以快速建立實(shí)現(xiàn)分布式服務(wù)贯莺。這些框架需要使用Spring Boot作為基礎(chǔ)開發(fā)平臺(tái)。學(xué)好了Spring Boot宁改,才能使用這些框架缕探,創(chuàng)建良好的Spring Cloud應(yīng)用。分布式應(yīng)用还蹲。訪問:https://spring.io/projects/spring-cloud

Spring Cloud包含的這些框架和工具各負(fù)其職爹耗,例如Spring Cloud Config提供配置中心的能力耙考,給分布式多個(gè)服務(wù)提供動(dòng)態(tài)的數(shù)據(jù)配置,像數(shù)據(jù)庫的url潭兽,用戶名和密碼等倦始,第三方接口數(shù)據(jù)等。 Spring Cloud Gateway網(wǎng)關(guān)讼溺,提供服務(wù)統(tǒng)一入口楣号,鑒權(quán),路由等功能怒坯。

學(xué)習(xí)Spring Colud難度比較大炫狱,里面框架,工具比較多剔猿。有多個(gè)框架需要學(xué)習(xí)视译,在把框架組合起來又是一個(gè)難度。

2.1.3 最新的Spring Boot3 新特性

2022年11月 24日归敬。Spring Boot3發(fā)布酷含,里程碑的重大發(fā)布。這個(gè)版本應(yīng)該是未來5年的使用主力汪茧。Spring官網(wǎng)支持Spring Boot3.0.X版本到2025年椅亚。SpringBoot3中的重大變化:1)JDK最小Java 17,能夠支持17-20.2)Spring Boot 3.0 已將所有底層依賴項(xiàng)從 Java EE 遷移到了 Jakarta EE API。原來javax開頭的包名舱污,修改為jakarta呀舔。 例如 jakarta.servlet.http.HttpServlet 原來javax.servlet.http.HttpServlet3)支持 GraalVM 原生鏡像。將Java應(yīng)用編譯為本機(jī)代碼扩灯,提供顯著的內(nèi)存和啟動(dòng)性能改進(jìn)媚赖。4)對(duì)第三方庫,更新了版本支持珠插。5)自動(dòng)配置文件的修改惧磺。6)提供新的聲明式Http服務(wù), 在接口方法上聲明@HttpExchange獲取http遠(yuǎn)程訪問的能力捻撑。代替OpenFeign7)Spring HTTP 客戶端提供基于 Micrometer 的可觀察性. 跟蹤服務(wù)磨隘,記錄服務(wù)運(yùn)行狀態(tài)等8)AOT(預(yù)先編譯) 支持Ahead Of Time,指運(yùn)行前編譯9)Servlet6.0規(guī)范10)支持 Jackson 2.14顾患。11)Spring MVC :默認(rèn)情況下使用的 PathPatternParser琳拭。刪除過時(shí)的文件和 FreeMarker 、JSP 支持描验。

伴隨著Spring Boot3的發(fā)布白嘁,還有 Spring Framework 6.0的發(fā)布(2022-11-16),先于Spring Boot發(fā)布。

2.1.4 如何學(xué)好框架

學(xué)習(xí)框架:我的建議無基礎(chǔ)膘流,先看視頻絮缅,照著例子做鲁沥;有基礎(chǔ)后自己做點(diǎn)程序。之后看圖書耕魄,最好是官網(wǎng)文檔画恰。不建議開始就看源代碼。

有基礎(chǔ)的:看圖書吸奴,最好是官網(wǎng)文檔允扇,邊看文檔邊實(shí)踐≡虬拢可以看框架此處功能的源代碼考润。不建議通篇看源代碼(在巨人身上是看不到全貌的)。提高部分看開源項(xiàng)目的代碼读处,最后寫項(xiàng)目糊治。

2.2 腳手架

腳手架是一種用在建筑領(lǐng)域的輔助工具,是為了保證建筑施工過程順利進(jìn)行而搭設(shè)的工作平臺(tái)罚舱。軟件工程中的腳手架是用來快速搭建一個(gè)小的可用的應(yīng)用程序的骨架井辜,將開發(fā)過程中要用到的工具、環(huán)境都配置好管闷,同時(shí)生成必要的模板代碼粥脚。腳手架輔助創(chuàng)建程序的工具,Spring Initializr是創(chuàng)建Spring Boot項(xiàng)目的腳手架包个∷⒃剩快速建立 Spring Boot項(xiàng)目的最好方式。他是一個(gè)web應(yīng)用赃蛛,能夠在瀏覽器中使用恃锉。IDEA中繼承了此工具搀菩,用來快速創(chuàng)建Spring Boot項(xiàng)目以及Spring Cloud項(xiàng)目呕臂。Spring Initializr腳手架的web地址:https://start.spring.io/阿里云腳手架:https://start.aliyun.com/

2.2.1 使用腳手架創(chuàng)建項(xiàng)目

1.瀏覽器訪問腳手架,創(chuàng)建項(xiàng)目2.IDEA中使用腳手架肪跋。

創(chuàng)建Spring Boot工程 Lesssion02-Project , Lession03-Project歧蒋。腳手架使用需要聯(lián)網(wǎng)。

2.2.2 IDEA創(chuàng)建SpringBoot項(xiàng)目

2.3 代碼結(jié)構(gòu)

2.3.1.1 單一模塊

一個(gè)工程一個(gè)模塊的完整功實(shí)現(xiàn)州既。創(chuàng)建學(xué)生模塊功能的Spring Boot項(xiàng)目Lession04-singlecom.example.模塊名稱+----Application.java 啟動(dòng)類+----controller?控制器包---StudentController.java---ScoreController.java+----service 業(yè)務(wù)層包---inter 業(yè)務(wù)層接口---impl 接口實(shí)現(xiàn)包+----repository 持久層包+----model 模型包---entity 實(shí)體類包---dto ? 數(shù)據(jù)傳輸包---vo ? ?視圖數(shù)據(jù)包

2.3.1.2 多個(gè)模塊

一個(gè)Spring Boot中多個(gè)模塊谜洽。在根包下創(chuàng)建每個(gè)模塊的子包, 子包中可以按“單一模塊”包結(jié)構(gòu)定義吴叶。創(chuàng)建包含多個(gè)功能的單體Spring Boot阐虚。 Lession05-crm (activity, sale, customer等模塊)

2.3.1.3 包和主類

我們通常建議您將主應(yīng)用程序類定位在其他類之上的根包中。@SpringBootApplication注釋通常放在主類上蚌卤,它隱式地為某些項(xiàng)定義了一個(gè)基本的“搜索包”实束。例如奥秆,如果您正在編寫一個(gè)JPA應(yīng)用程序,則使用@SpringBootApplication注釋類的包來搜索@Entity項(xiàng)咸灿。使用根包還允許組件掃描只應(yīng)用于您的項(xiàng)目构订。

Spring Boot支持基于java的配置。盡管可以將SpringApplication與XML源一起使用避矢,但我們通常建議您的主源是單個(gè)@Configuration類悼瘾。通常,定義主方法的類可以作為主@Configuration類审胸。

2.3.1.4 spring-boot-starter-parent

pom.xml中的指定spring-boot-starter-parent作為坐標(biāo)亥宿,表示繼承Spring Boot提供的父項(xiàng)目。從 spring-boot-starter-parent 繼承以獲得合理的默認(rèn)值和完整的依賴樹歹嘹,以便快速建立一個(gè)Spring Boot項(xiàng)目箩绍。 父項(xiàng)目提供以下功能:

[if !supportLists]·?[endif]JDK的基準(zhǔn)版本,比如<java.version>17</java.version>

[if !supportLists]·?[endif]源碼使用UTF-8 格式編碼

[if !supportLists]·?[endif]公共依賴的版本

[if !supportLists]·?[endif]自動(dòng)化的資源過濾:默認(rèn)把src/main/resources目錄下的文件進(jìn)行資源打包

[if !supportLists]·?[endif]maven的占位符為‘@’

[if !supportLists]·?[endif]對(duì)多個(gè)Maven插件做了默認(rèn)配置尺上,如maven-compile-plugin材蛛,maven-jar-plugin

快速創(chuàng)建Spring Boot項(xiàng)目,同時(shí)能夠使用父項(xiàng)目帶來的便利性怎抛,可以采用如下兩種方式:1.在項(xiàng)目中卑吭,繼承spring-boot-starter-parent2.pom.xml不繼承,單獨(dú)加入spring-boot-dependencies依賴马绝。

<dependencyManagement>??

<dependencies>???

?<dependency>??????

<groupId>org.springframework.boot</groupId>??????

<artifactId>spring-boot-dependencies</artifactId>??????

<version>3.0.1</version>??????

<type>pom</type>??????

<scope>import</scope>???

?</dependency>??

</dependencies></dependencyManagement>

2.4 運(yùn)行Spring Boot項(xiàng)目方式

[if !supportLists]·?[endif]開發(fā)工具豆赏,例如IDEA 執(zhí)行main方法

[if !supportLists]·?[endif]Maven插件 mvn spring-boot:run

[if !supportLists]·?[endif]java -jar jar文件的路徑

Spring Boot項(xiàng)目可以打包為jar或者war文件。 因?yàn)镾pring Boot內(nèi)嵌了web服務(wù)器富稻,例如tomcat掷邦。能夠以jar方式運(yùn)行web應(yīng)用。 無需安裝tomcat程序椭赋。

創(chuàng)建Lession06-package演示打包jar應(yīng)用抚岗。

更進(jìn)一步普通的jar與Spring Boot jar區(qū)別:

項(xiàng)目spring boot jar普通的jar

目錄BOOT-INF : 應(yīng)用的class和依賴jarMETA-INF: 清單

org.springframework.boot.loader: spring-boot-loader模塊類

META-INF:清單

class的文件夾:jar中的所有類

目錄class:應(yīng)用的類lib:應(yīng)用的依賴沒有BOOT-INF

spring-boot-loader執(zhí)行jar的spring boot類沒有此部分

可執(zhí)行

命令:powershell中 tree?/FSpring Boot jar文件的結(jié)構(gòu):


2.5 starter

starter是一組依賴描述,應(yīng)用中包含starter哪怔,可以獲取spring相關(guān)技術(shù)的一站式的依賴和版本宣蔚。不必復(fù)制、粘粘代碼认境。通過starter能夠快速啟動(dòng)并運(yùn)行項(xiàng)目胚委。starter包含:

[if !supportLists]1.?[endif]依賴坐標(biāo)、版本

[if !supportLists]2.?[endif]傳遞依賴的坐標(biāo)叉信、版本

[if !supportLists]3.?[endif]配置類亩冬,配置項(xiàng)

pom.xml 加入mybatis依賴

<dependency>?

?<groupId>org.mybatis.spring.boot</groupId>??

<artifactId>mybatis-spring-boot-starter</artifactId>??

<version>2.2.2</version>

</dependency>

查看Maven依賴


MyBatis 配置類


2.6 外部化配置

應(yīng)用程序=?代碼 ?+ 數(shù)據(jù)(數(shù)據(jù)庫,文件硼身,url)應(yīng)用程序的配置文件:Spring Boot允許在代碼之外硅急,提供應(yīng)用程序運(yùn)行的數(shù)據(jù)枢冤,以便在不同的環(huán)境中使用相同的應(yīng)用程序代碼。避免硬編碼铜秆,提供系統(tǒng)的靈活性淹真。可使用各種外部配置源连茧,包括Java屬性文件核蘸、YAML文件、環(huán)境變量和命令行參數(shù)啸驯。項(xiàng)目中經(jīng)常使用properties與yaml文件客扎,其次是命令行參數(shù)

2.6.1配置文件基礎(chǔ)2.6.1.1 配置文件格式

配置文件有兩種格式分別:properies 和yaml(yml)。properties是Java中的常用的一種配置文件格式罚斗,key=value徙鱼。key是唯一的,文件擴(kuò)展名為properties针姿。yaml(YAML Ain't Markup Language)也看做是yml袱吆,是一種做配置文件的數(shù)據(jù)格式,基本的語法 key:[空格]值距淫。yml文件文件擴(kuò)展名是yaml或yml(常用)绞绒。

yml格式特點(diǎn):YAML基本語法規(guī)則:

[if !supportLists]·?[endif]大小寫敏感

[if !supportLists]·?[endif]使用縮進(jìn)表示層級(jí)關(guān)系

[if !supportLists]·?[endif]縮進(jìn)只可以使用空格,不允許使用Tab鍵

[if !supportLists]·?[endif]縮進(jìn)的空格數(shù)目不重要榕暇,相同層級(jí)的元素左側(cè)對(duì)齊即可

[if !supportLists]·?[endif]#字符表示注釋蓬衡,只支持單行注釋。#放在注釋行的第一個(gè)字符YAML縮進(jìn)必須使用空格彤枢,而且區(qū)分大小寫狰晚,建議編寫YAML文件只用小寫和空格。

YAML支持三種數(shù)據(jù)結(jié)構(gòu)

[if !supportLists]·?[endif]對(duì)象:鍵值對(duì)的集合缴啡,又稱為映射(mapping)/ 哈希(hashes) / 字典(dictionary)

[if !supportLists]·?[endif]數(shù)組:一組按次序排列的值壁晒,又稱為序列(sequence) / 列表(list)

[if !supportLists]·?[endif]標(biāo)量(scalars):單個(gè)的、不可再分的值盟猖,例如數(shù)字讨衣、字符串换棚、true|false等需要掌握數(shù)據(jù)結(jié)構(gòu)完整內(nèi)容式镐,可從https://yaml.org/type/index.html獲取詳細(xì)介紹。

2.6.1.2 application文件

Spring Boot同時(shí)支持properties和yml格式的配置文件固蚤。 配置文件名稱默認(rèn)是application娘汞。我們可以使用application.properties , application.yml。讀取配置文件的key值夕玩,注入到Bean的屬性可用@Value你弦,@Value一次注入一個(gè)key的值惊豺。將多個(gè)key值綁定到Bean的多個(gè)屬性要用到@ConfigurationProperties注解。在代碼中訪問屬性除了注解禽作,Spring提供了外部化配置的抽象對(duì)象Environment尸昧。Environment包含了幾乎所有外部配置文件,環(huán)境變量旷偿,命令行參數(shù)等的所有key和value烹俗。需要使用Environment的注入此對(duì)象,調(diào)用它的getProperty(String ?key)方法即可萍程。

創(chuàng)建新的Spring Boot練習(xí)配置文件的使用幢妄,項(xiàng)目名稱 Lession07-config。Maven作為構(gòu)建工具茫负,JDK19蕉鸳。包名com.bjpowernode.config 。不需要其他依賴忍法。

更進(jìn)一步

Spring Boot建議使用一種格式的配置文件潮尝,如果properties和yml都存在。properties文件優(yōu)先饿序。推薦使用yml文件衍锚。application配置文件的名稱和位置都可以修改。約定名稱為application嗤堰,位置為resources目錄戴质。

2.6.1.3 application.properties

需求:在application.properties 提供應(yīng)用程序的name,owner, port基本信息踢匣,程序讀取這些數(shù)據(jù)告匠,顯示給用戶。step1:在application.properties自定義配置項(xiàng)目

step2: 創(chuàng)建SomeService類讀取app.name, app.owner,app.port配置key离唬。注解@Value讀取單個(gè)值后专,語法${key:默認(rèn)值}

step3:單元測(cè)試在test目錄下創(chuàng)建測(cè)試類,注入SomeService對(duì)象输莺,調(diào)用它的printValue()方法戚哎。

@SpringBootTest ?public class TestPropConfig {

@Autowired ?

private SomeService service;

@Test ?

void test01() {

service.printValue();

}

}

輸出:result = Lession07;changming;8001

2.6.1.4 application.yml

需求:同上面一樣的需求,配置為application.yml嫂用。首先修改application.properties名稱為其他的任意名稱型凳,比如1appliction.properties。在創(chuàng)建application.yml文件嘱函。SomeService類不用修改甘畅。

step1:編寫application.yml

step2: 運(yùn)行單元測(cè)試TestPropConfig#test01()輸出:result = Lession07-yml;bjpowernode;8002

Spring Boot對(duì)yml文件的內(nèi)容進(jìn)行扁平化處理。將yml中的內(nèi)容看做和properties中的格式一樣處理。也就是app: name 看做是app.name疏唾。 所以在程序中Spring Boot認(rèn)為properties和yml是一樣的蓄氧。

2.6.1.5 Environment

Environment是外部化的抽象,是多種數(shù)據(jù)來源的集合槐脏。從中可以讀取application配置文件喉童,環(huán)境變量,系統(tǒng)屬性顿天。使用方式在Bean中注入Environment泄朴。調(diào)用它的getProperty(key)方法。

step1:創(chuàng)建ReadConfig類露氮,注入Environment

@Service ?

public class ReadConfig {

@Autowired ?private Environment environment;

public void print(){

String name = environment.getProperty("app.name");

//key是否存在

if (environment.containsProperty("app.owner")) {

System.out.println("有app.owner配置項(xiàng)");

}

//讀取key轉(zhuǎn)為需要的類型祖灰,提供默認(rèn)值8000

Integer port = environment.getProperty("app.port", Integer.class, 8000);

String result = String.format("讀取的name:%s,端口port:%d", name,port);

System.out.println("result = " + result);

}

}

step2:單元測(cè)試

@SpringBootTest ?

class ReadConfigTest {

@Autowired ?

private ReadConfig readConfig;

@Test ?

void test01() {

readConfig.print();

}

}

輸出:有app.owner配置項(xiàng)result = 讀取的name:Lession07-yml畔规,端口port:8002

2.6.1.6 組織多文件

大型集成的第三方框架局扶,中間件比較多。每個(gè)框架的配置細(xì)節(jié)相對(duì)復(fù)雜叁扫。如果都將配置集中到一個(gè)application文件三妈,導(dǎo)致文件內(nèi)容多,不易于閱讀莫绣。我們將每個(gè)框架獨(dú)立一個(gè)配置文件畴蒲,最后將多個(gè)文件集中到application。我們使用導(dǎo)入文件的功能对室。需求:項(xiàng)目集成redis模燥,數(shù)據(jù)庫mysql。 將redis掩宜,數(shù)據(jù)庫單獨(dú)放到獨(dú)立的配置文件蔫骂。

step1:在resources創(chuàng)建自定義conf目錄,在conf中創(chuàng)建redis.yml, db.yml

step2: application.yml導(dǎo)入多個(gè)配置

step3:創(chuàng)建類牺汤,讀取兩個(gè)文件的配置項(xiàng)

@Service ?

public class MultiConfigService {

@Value("${spring.redis.host}")

private String redisHost;

@Value("${spring.datasource.url}")

private String dbUrl;

public void printConfig(){

System.out.println("redis的ip:"+redisHost+"辽旋,數(shù)據(jù)庫url;"+dbUrl);

}

}

step4: 單元測(cè)試

@SpringBootTest ?

class MultiConfigServiceTest {

@Autowired ?

private MultiConfigService multiConfigService;

@Test ?

void test01() {

multiConfigService.printConfig();

}

}

輸出:redis的ip:192.168.1.10檐迟,數(shù)據(jù)庫url补胚;jdbc:mysql://192.168.1.21/db?serverTime=Asia/Shanghai

2.6.1.7 多環(huán)境配置

軟件開發(fā)中經(jīng)常提到環(huán)境這個(gè)概念,與日常生活中的環(huán)境概念一樣追迟。環(huán)境影響居住體驗(yàn)溶其。影響軟件運(yùn)行的也叫做環(huán)境,例如應(yīng)用中訪問數(shù)據(jù)庫的ip怔匣,用戶名和密碼握联,Redis的端口,配置文件的路徑每瞒,windows金闽,linux系統(tǒng),tomcat服務(wù)器等等剿骨。圍繞著程序周圍的都是環(huán)境代芜。環(huán)境影響軟件的運(yùn)行。Spring Profiles表示環(huán)境浓利,Profiles有助于隔離應(yīng)用程序配置挤庇,并使它們僅在某些環(huán)境中可用。常說開發(fā)環(huán)境贷掖,測(cè)試環(huán)境嫡秕,生產(chǎn)環(huán)境等等。一個(gè)環(huán)境就是一組相關(guān)的配置數(shù)據(jù)苹威, 支撐我們的應(yīng)用在這些配置下運(yùn)行昆咽。應(yīng)用啟動(dòng)時(shí)指定適合的環(huán)境。開發(fā)環(huán)境下每個(gè)開發(fā)人員使用自己的數(shù)據(jù)庫ip牙甫,用戶掷酗,redis端口。 同一個(gè)程序現(xiàn)在要測(cè)試了窟哺。需要把數(shù)據(jù)庫ip泻轰,redis的改變?yōu)闇y(cè)試服務(wù)器上的信息。 此時(shí)使用多環(huán)境能夠方便解決這個(gè)問題且轨。Spring Boot規(guī)定環(huán)境文件的名稱 application-{profile}.properties(yml)浮声。其中profile為自定義的環(huán)境名稱,推薦使用dev表示開發(fā) 旋奢,test表示測(cè)試阿蝶。 prod表示生產(chǎn),feature表示特性黄绩∠劢啵總是profile名稱是自定義的。Spring Boot會(huì)加載application 以及 application-{profile}兩類文件爽丹,不是只單獨(dú)加載application-{profile}筑煮。需求: 項(xiàng)目使用多環(huán)境配置,準(zhǔn)備一個(gè)開發(fā)環(huán)境粤蝎,一個(gè)測(cè)試環(huán)境

step1:在resources創(chuàng)建環(huán)境配置文件

step2: 激活環(huán)境

spring: config:#導(dǎo)入多個(gè)配置文件真仲,“,”作為分隔符 import: conf/db.yml,conf/redis.yml#激活環(huán)境初澎,與on-profile名稱保持一致 profiles: active: dev

spring.profiles.active: 環(huán)境名稱

step3: 創(chuàng)建讀取配置項(xiàng)的類

@Service ?

public class MulitEnvService {

@Value("${myapp.memo}")

private String memo;

public void print(){

System.out.println(memo);

}

}

step4: 單元測(cè)試

@SpringBootTest ?

class MulitEnvServiceTest {

@Autowired ?

private MulitEnvService service;

@Test ?

void test01() {service.print();

}

}

2.6.2 綁定Bean

@Value綁定單個(gè)屬性秸应,當(dāng)屬性較多時(shí)不方便虑凛,Spring Boot提供了另一種屬性的方法。將多個(gè)配置項(xiàng)綁定到Bean的屬性软啼,提供強(qiáng)類型的Bean桑谍。Bean能夠訪問到配置數(shù)據(jù)』雠玻基本原則:標(biāo)準(zhǔn)的Java Bean有無參數(shù)構(gòu)造方法锣披,包含屬性的訪問器。配合@ConfigurationProperties 注解一起使用贿条。Bean的static屬性不支持雹仿。

Spring Boot自動(dòng)配置中大量使用了綁定Bean與@ConfigurationProperties,提供對(duì)框架的定制參數(shù)整以。項(xiàng)目中要使用的數(shù)據(jù)如果是可變的胧辽,推薦在yml或properties中提供。項(xiàng)目代碼具有較大的靈活性公黑。@ConfigurationProperties能夠配置多個(gè)簡單類型屬性票顾,同時(shí)支持Map,List帆调,數(shù)組類型奠骄。對(duì)屬性還能驗(yàn)證基本格式。

2.6.2.1 簡單的屬性綁定

使用之前的app開頭的配置內(nèi)容番刊。yml含鳞,properties配置格式都可以,綁定Bean的效果都一樣芹务。step1:查看application配置蝉绷。目前使用的是application.yml


step2: 創(chuàng)建Bean,定義name枣抱,owner, port屬性

@Configuration(proxyBeanMethods ?= false) @ConfigurationProperties(prefix ?= "app") public class AppBean {private String name;private String owner;private Integer port;// set | get方法 ,toString()}

@ConfigurationProperties聲明在類上熔吗,表示綁定屬性到此類。prefix表示前綴佳晶,是配置文件中多個(gè)key的公共前綴桅狠。這些key以“.”作為分隔符。例如app.name, app: name等轿秧。 prefix=”app”, 將文件中app開始的key都找到中跌,調(diào)用與key相同名稱的setXXX方法。如果有給屬性賦值成功菇篡。沒有的忽略漩符。

step3:單元測(cè)試

@SpringBootTest ?class AppBeanTest {@Autowired ?private AppBean appBean;@Test ?void test01() {System.out.println("appBean.toString() = " + appBean.toString());}}

輸出:AppBean的所有屬性值。

2.6.2.2 嵌套Bean

需求:Bean中包含其他Bean作為屬性驱还,將配置文件中的配置項(xiàng)綁定到Bean以及引用類型的成員嗜暴。Bean的定義無特殊要求凸克。在原來的app的配置中,增加security相關(guān)配置闷沥,包含username萎战,password兩個(gè)屬性。

step1: 定義兩個(gè)Bean

public class Security {private String username;private String password;// set | get方法 ,toString()}@Configuration(proxyBeanMethods ?= false) @ConfigurationProperties(prefix ?= "app") public class NestAppBean {private String name;private String owner;private Integer port;private Security security;// set | get方法 ,toString()}

step2: 定義application.yml

#yml配置文件 ?key: 值app:name: Lession07-ymlowner: bjpowernodeport: 8002app.security.username=rootapp.security.password=123456security:username: rootpassword: 123456

step3: 單元測(cè)試

@SpringBootTest ?class NestAppBeanTest {@Autowired ?private NestAppBean appBean;@Test ?void test01() {System.out.println("appBean.toString() = " + appBean.toString());}}

輸出:appBean.toString() = NestAppBean{name='Lession07-yml', owner='bjpowernode', port=8002, security=Security{username='root', password='123456'}}

2.6.2.3 掃描注解

@ConfigurationProperties注解起作用狐赡,還需要@EnableConfigurationProperties或@ConfigurationPropertiesScan撞鹉。 這個(gè)注解是專門尋找@ConfigurationProperties注解的疟丙,將他的對(duì)象注入到Spring容器颖侄。在啟動(dòng)類上使用掃描注解。

/**● 掃描@ConfigurationProperties所在的包名● 不掃描@Component ?*/@ConfigurationPropertiesScan({"com.bjpowernode.config.pk4"})@SpringBootApplicationpublic class Lession07ConfigApplication {public static void main(String[] args) {SpringApplication.run(Lession07ConfigApplication.class, args);}}

2.6.2.4 處理第三方庫對(duì)象

上面的例子都是在源代碼中使用@ConfigurationProperties注解享郊,如果某個(gè)類需要在配置文件中提供數(shù)據(jù)览祖,但是沒有源代碼。此時(shí)@ConfigurationProperties結(jié)合@Bean一起在方法上面使用炊琉。比如現(xiàn)在有一個(gè)Security類是第三方庫中的類展蒂,現(xiàn)在要提供它的username,password屬性值苔咪。

step1: application.yml添加新的配置

security:username: commonpassword: abc123

step2:創(chuàng)建配置類

@Configuration ?public class ApplicationConfig {@ConfigurationProperties(prefix ?= "security") @Bean ?public Security createSecurity(){return new Security();}}

step3: 單元測(cè)試

@SpringBootTest ?public class BeanMethodTest {@Autowired ?private Security security;@Test ?void test01() {System.out.println("security = " + security);}}

輸出:security = Security{username='common', password='abc123'}

2.6.2.5 集合Map锰悼,List以及Array

Map,List以及Array都能提供配置數(shù)據(jù)团赏, 下面通過一個(gè)示例配置集合屬性箕般。

step1:創(chuàng)建保存數(shù)據(jù)的Bean

public class User {private String name;private String sex;private Integer age;//set | get ,toString}public class MyServer {private String title;private String ip;//set | get ,toString}@ConfigurationPropertiespublic class CollectionConfig {private List servers;private Map<String,User> users;private String [] names;//set | get ,toString}

step2: 修改application.yml, 配置數(shù)據(jù)

#集合以及數(shù)組#List namesnames:-lisi-zhangsan#List serversservers:- title: 華北服務(wù)器ip: 202.12.39.1- title: 西南服務(wù)器ip: 106.90.23.229- title: 南方服務(wù)器ip: 100.21.56.23#Map<String,User> usersusers:user1:name: 張三sex: 男age: 22user2:name: 李四sex: 男age: 26

“-”表示集合一個(gè)成員,因?yàn)槌蓡T是對(duì)象舔清,需要屬性名稱指定屬性值丝里。List與數(shù)組前面加入“-”表示一個(gè)成員。Map直接指定key和value体谒,無需“-”杯聚。

step3: 啟動(dòng)類,增加掃描包

/**● 掃描@ConfigurationProperties所在的包名● 不掃描@Component ?*/@ConfigurationPropertiesScan({"其他包","com.bjpowernode.config.pk5"})@SpringBootApplicationpublic class Lession07ConfigApplication {public static void main(String[] args) {SpringApplication.run(Lession07ConfigApplication.class, args);}}

com.bjpowernode.config.pk5是新增的包抒痒, 按自己的包結(jié)構(gòu)指定名稱幌绍。

step4:單元測(cè)試

@SpringBootTest ?class CollectionConfigTest {@Autowired ?private CollectionConfig collectionConfig;@Test ?void test01() {String str = collectionConfig.toString();System.out.println("str = " + str);}}

輸出Bean的屬性值str = CollectionConfig{servers=[MyServer{title='華北服務(wù)器', ip='202.12.39.1'}, MyServer{title='西南服務(wù)器', ip='106.90.23.229'}, MyServer{title='南方服務(wù)器', ip='100.21.56.23'}], users={user1=User{name='張三', sex='男', age=22}, user2=User{name='李四', sex='男', age=26}}, names=[lisi, zhangsan]}

2.6.2.6 指定數(shù)據(jù)源文件

application做配置是經(jīng)常使用的,除以以外我們能夠指定某個(gè)文件作為數(shù)據(jù)來源故响。@PropertySource是注解纷捞,用以加載指定的properties文件。也可以是XML文件(無需了解)被去。@PropertySource與@Configuration一同使用主儡,其他注解還有@Value,@ConfigurationProperties惨缆。

需求:一個(gè)組織信息糜值,在單獨(dú)的properties文件提供組織的名稱丰捷,管理者和成員數(shù)量

step1: 創(chuàng)建Group類,表示組織

@Configuration ?@ConfigurationProperties(prefix ?= "group") @PropertySource(value ?= "classpath:/group-info.properties") public class Group {private String name;private String leader;private Integer members;//set | get ,toString}

step2:在resources目錄下的任意位置創(chuàng)建properties文件寂汇,我們創(chuàng)建group-info.properties病往,放在resources根目錄。


step3: 單元測(cè)試

@SpringBootTest ?class GroupTest {@Autowired ?private Group group;@Test ?void test01() {System.out.println("group = " + group.toString());}}

控制臺(tái)輸出:group = Group{name='IT學(xué)習(xí)專欄', leader='無名', members=500}

總結(jié):@ConfigurationProperties綁定Bean對(duì)于使用配置文件的數(shù)據(jù)是十分方便骄瓣,靈活的停巷。也支持對(duì)數(shù)據(jù)的校驗(yàn),校驗(yàn)是JSR303規(guī)范中的注解榕栏。Bean定義結(jié)合Lombok會(huì)更加方便畔勤。如果團(tuán)隊(duì)都接受Lombok。 推薦使用扒磁。

2.7 創(chuàng)建對(duì)象三種方式

將對(duì)象注入到Sprin容器庆揪,可以通過如下方式:

[if !supportLists]·?[endif]傳統(tǒng)的XML配置文件

[if !supportLists]·?[endif]Java Config技術(shù), @Configuration與@Bean

[if !supportLists]·?[endif]創(chuàng)建對(duì)象的注解妨托,@Controller 缸榛,@Service , @Repository 兰伤,@Component

Spring Boot不建議使用xml文件的方式内颗, 自動(dòng)配置已經(jīng)解決了大部分xml中的工作了。如果需要xml提供bean的聲明敦腔,@ImportResource加載xml注冊(cè)Bean均澳。

需求:XML配置Spring容器。聲明Beanstep1: 創(chuàng)建Person類会烙,對(duì)象由容器管理

public class Person {private String name;private Integer age;//set | get ,toString}

step2:resources目錄下創(chuàng)建XML配置文件

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"??xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">??<bean id="myPerson" class="com.bjpowernode.config.pk7.Person">????<property name="name" value="李四" />????<property name="age" value="20" />??</bean></beans>

step3: 啟動(dòng)類负懦,從容器中獲取Person對(duì)象

@ImportResource(locations ?= "classpath:/applicationContext.xml") @ConfigurationPropertiesScan({"com.bjpowernode.config.pk4","com.bjpowernode.config.pk5"})@SpringBootApplicationpublic class Lession07ConfigApplication {public static void main(String[] args) {ApplicationContext ctx =SpringApplication.run(Lession07ConfigApplication.class, args);Person myPerson = (Person) ctx.getBean("myPerson");System.out.println("myPerson = " + myPerson);}}

@ImportResource(locations ?= "classpath:/applicationContext.xml"), 加載類路徑下的applicationContext.xml文件柏腻。location或者value屬性都能指定文件路徑纸厉。

2.8 AOP

AOP(Aspect Oriented Programming):面向切面編程,保持原有代碼不變五嫂,能夠給原有的業(yè)務(wù)邏輯增加二維的功能颗品。AOP增加的功能是開發(fā)人員自己編寫的,底層是動(dòng)態(tài)代理實(shí)現(xiàn)功能的增強(qiáng)沃缘。對(duì)于擴(kuò)展功能十分有利躯枢。Spring的事務(wù)功能就是在AOP基礎(chǔ)上實(shí)現(xiàn)的, 業(yè)務(wù)方法在執(zhí)行前【開啟事務(wù)】槐臀,在執(zhí)行業(yè)務(wù)方法锄蹂,最后【提交或回滾失敗】。

[if !supportLists]·?[endif]Aspect:表示切面水慨,開發(fā)自己編寫功能增強(qiáng)代碼的地方得糜,這些代碼會(huì)通過動(dòng)態(tài)代理加入到原有的業(yè)務(wù)方法中敬扛。@Aspect注解表示當(dāng)前類是切面類。 切面類是一個(gè)普通類朝抖。

[if !supportLists]·?[endif]Joinpoint:表示連接點(diǎn)啥箭,連接切面和目標(biāo)對(duì)象≈涡或是一個(gè)方法名稱急侥,一個(gè)包名,類名侮邀。在這個(gè)特定的位置執(zhí)行切面中的功能代碼坏怪。

[if !supportLists]·?[endif]切入點(diǎn)(Pointcut):其實(shí)就是篩選出的連接點(diǎn)差购。一個(gè)類中的所有方法都可以是JoinPoint, 具體的那個(gè)方法要增加功能,這個(gè)方法就是Pointcut各墨。

[if !supportLists]·?[endif]Advice:翻譯是通知置尔,也叫做增強(qiáng)。表示增強(qiáng)的功能執(zhí)行時(shí)間照棋。 Java代碼執(zhí)行的單位是方法,方法是業(yè)務(wù)邏輯代碼,在方法之前增加新的功能唯绍,還是方法之后增加功能。 表示在方法前枝誊,后等的就是通知况芒。

主要包括5個(gè)注解:@Before,@After叶撒,@AfterReturning绝骚,@AfterThrowing,@Around祠够。注解來自aspectj框架压汪。@Before:在切點(diǎn)方法之前執(zhí)行。@After:在切點(diǎn)方法之后執(zhí)行@AfterReturning:切點(diǎn)方法返回后執(zhí)行@AfterThrowing:切點(diǎn)方法拋異常執(zhí)行@Around:屬于環(huán)繞增強(qiáng)古瓤,能控制切點(diǎn)執(zhí)行前止剖,執(zhí)行后。功能最強(qiáng)的注解落君。

[if !supportLists]·?[endif]Target Object: 目標(biāo)對(duì)象穿香。 在A類的print()方法執(zhí)行前, 輸出方法的執(zhí)行時(shí)間绎速。 也就是給A這個(gè)對(duì)象增加了“輸出執(zhí)行時(shí)間的功能”皮获。

AOP技術(shù)主要的實(shí)現(xiàn)一個(gè)是Spring框架,Spring Boot當(dāng)然支持AOP纹冤;另一個(gè)是功能全面的AspectJ框架洒宝。Spring Boot執(zhí)行AspectJ框架主届。使用@Before,@After待德,@AfterReturning君丁,@AfterThrowing,@Around注解的方式就來自AspectJ框架的功能将宪。

需求:項(xiàng)目中的業(yè)務(wù)方法都需要在日志中輸出方法調(diào)用的時(shí)間以及參數(shù)明細(xì)绘闷。業(yè)務(wù)方法多,使用AOP最合適较坛。新建Spring Boot項(xiàng)目Lession08-aop , Maven管理項(xiàng)目印蔗,無需選擇依賴。包名稱丑勤。com.bjpowernode.aop

step1:Maven添加aop依賴

<dependency>??<groupId>org.springframework.boot</groupId>??<artifactId>spring-boot-starter-aop</artifactId></dependency>

包含了aop和aspectj依賴

step2:創(chuàng)建業(yè)務(wù)類SomeService在aop的service子包

package com.bjpowernode.aop.service;public interface SomeService {void query(Integer id);void save(String name, String code);}實(shí)現(xiàn)類:import org.springframework.stereotype.Service;@Service ?public class SomeServiceImpl implements SomeService {@Override ?public void query(Integer id) {System.out.println("SomeService業(yè)務(wù)方法query執(zhí)行了");}@Override ?public void save(String name, String code) {System.out.println("SomeService業(yè)務(wù)方法save執(zhí)行了");}}

step3:創(chuàng)建切面類

@Component ?@Aspect ?public class LogAspect {//前置通知 execution是切入點(diǎn)表達(dá)式@Before("execution( com.bjpowernode.aop.service...*(..))")public void sysLog(JoinPoint jp){StringJoiner log = new StringJoiner("|", "{", "}");DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");log.add(formatter.format(LocalDateTime.now()));//目標(biāo)方法參數(shù)列表Object[] args = jp.getArgs();for (Object arg : args) {??log.add( arg == null ? "-" : arg.toString());}System.out.println("方法執(zhí)行日志:" + log.toString());}}

@Aspect說明當(dāng)前類是切面類华嘹,包含了功能增強(qiáng)的代碼和通知注解。@Component 將切面類對(duì)象注入到spring容器法竞。spring會(huì)根據(jù)目標(biāo)類和切面類創(chuàng)建代理對(duì)象耙厚,織入切面功能。

step4:單元測(cè)試

@SpringBootTest ?public class AspectTest {@Autowired ?private SomeService service;@Test ?void testLog() {service.query(1001);service.save("訂單業(yè)務(wù)", "B01256");}}

輸出執(zhí)行結(jié)果:方法執(zhí)行日志:{2023-01-22 13:52:43|1001}SomeService業(yè)務(wù)方法query執(zhí)行了方法執(zhí)行日志:{2023-01-22 13:52:43|訂單業(yè)務(wù)|B01256}SomeService業(yè)務(wù)方法save執(zhí)行了

結(jié)論:在業(yè)務(wù)方法前岔霸,先執(zhí)行了切面類中sysLog()的功能增強(qiáng)代碼薛躬。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市呆细,隨后出現(xiàn)的幾起案子型宝,更是在濱河造成了極大的恐慌,老刑警劉巖絮爷,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趴酣,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡坑夯,警方通過查閱死者的電腦和手機(jī)岖寞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渊涝,“玉大人慎璧,你說我怎么就攤上這事】缡停” “怎么了胸私?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鳖谈。 經(jīng)常有香客問我岁疼,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任捷绒,我火速辦了婚禮瑰排,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘暖侨。我一直安慰自己椭住,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布字逗。 她就那樣靜靜地躺著京郑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葫掉。 梳的紋絲不亂的頭發(fā)上些举,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音俭厚,去河邊找鬼户魏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛挪挤,可吹牛的內(nèi)容都是我干的叼丑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼电禀,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼幢码!你這毒婦竟也來了笤休?” 一聲冷哼從身側(cè)響起尖飞,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎店雅,沒想到半個(gè)月后政基,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闹啦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年沮明,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窍奋。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荐健,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出琳袄,到底是詐尸還是另有隱情江场,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布窖逗,位于F島的核電站址否,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏碎紊。R本人自食惡果不足惜佑附,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一樊诺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧音同,春花似錦词爬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至螺句,卻和暖如春虽惭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蛇尚。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工芽唇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人取劫。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓匆笤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谱邪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子炮捧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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