10月阿里面試總結(jié):必問的Spring面試解析择份,面試時(shí)要注意的那些坑

前言:

作為 Java 的從業(yè)者扣孟,在找工作的時(shí)候,一定會(huì)被問及關(guān)于 Spring相關(guān)的知識(shí)荣赶。 Spring知識(shí)的掌握程度凤价,在很多面試官眼里是候選人技術(shù)深度的一個(gè)重要評(píng)判標(biāo)準(zhǔn)。 在這里我們將詳細(xì)的整理常見的 Spring 面試題目拔创,并給出標(biāo)準(zhǔn)答案料仗,提供給大家學(xué)習(xí)參考。等大家面試的時(shí)候伏蚊,希望能對(duì)面試官吹個(gè)半個(gè)小時(shí),如果真是這樣格粪,我想說:牛皮磅锏酢!

另外本人整理收藏了20年多家公司面試知識(shí)點(diǎn)整理 帐萎,以及各種Java核心知識(shí)點(diǎn)免費(fèi)分享給大家比伏,想要資料的話請(qǐng)點(diǎn)930573664暗號(hào)簡書。

Spring概述(10)

什么是spring?

Spring是一個(gè)輕量級(jí)Java開發(fā)框架疆导,最早有Rod Johnson創(chuàng)建赁项,目的是為了解決企業(yè)級(jí)應(yīng)用開發(fā)的業(yè)務(wù)邏輯層和其他各層的耦合問題。它是一個(gè)分層的JavaSE/JavaEE full-stack(一站式)輕量級(jí)開源框架澈段,為開發(fā)Java應(yīng)用程序提供全面的基礎(chǔ)架構(gòu)支持悠菜。Spring負(fù)責(zé)基礎(chǔ)架構(gòu),因此Java開發(fā)者可以專注于應(yīng)用程序的開發(fā)败富。

Spring最根本的使命是解決企業(yè)級(jí)應(yīng)用開發(fā)的復(fù)雜性悔醋,即簡化Java開發(fā)

Spring可以做很多事情兽叮,它為企業(yè)級(jí)開發(fā)提供給了豐富的功能芬骄,但是這些功能的底層都依賴于它的兩個(gè)核心特性猾愿,也就是依賴注入(dependency injection,DI)和面向切面編程(aspect-oriented programming账阻,AOP)蒂秘。

為了降低Java開發(fā)的復(fù)雜性,Spring采取了以下4種關(guān)鍵策略

  • 基于POJO的輕量級(jí)和最小侵入性編程淘太;
  • 通過依賴注入和面向接口實(shí)現(xiàn)松耦合姻僧;
  • 基于切面和慣例進(jìn)行聲明式編程;
  • 通過切面和模板減少樣板式代碼琴儿。

Spring框架的設(shè)計(jì)目標(biāo)段化,設(shè)計(jì)理念,和核心是什么

Spring設(shè)計(jì)目標(biāo):Spring為開發(fā)者提供一個(gè)一站式輕量級(jí)應(yīng)用開發(fā)平臺(tái)造成;

Spring設(shè)計(jì)理念:在JavaEE開發(fā)中显熏,支持POJO和JavaBean開發(fā)方式,使應(yīng)用面向接口開發(fā)晒屎,充分支持OO(面向?qū)ο螅┰O(shè)計(jì)方法喘蟆;Spring通過IoC容器實(shí)現(xiàn)對(duì)象耦合關(guān)系的管理,并實(shí)現(xiàn)依賴反轉(zhuǎn)鼓鲁,將對(duì)象之間的依賴關(guān)系交給IoC容器蕴轨,實(shí)現(xiàn)解耦;

Spring框架的核心:IoC容器和AOP模塊骇吭。通過IoC容器管理POJO對(duì)象以及他們之間的耦合關(guān)系橙弱;通過AOP以動(dòng)態(tài)非侵入的方式增強(qiáng)服務(wù)。

IoC讓相互協(xié)作的組件保持松散的耦合燥狰,而AOP編程允許你把遍布于應(yīng)用各層的功能分離出來形成可重用的功能組件棘脐。

Spring的優(yōu)缺點(diǎn)是什么?

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

  • 方便解耦龙致,簡化開發(fā)

    Spring就是一個(gè)大工廠蛀缝,可以將所有對(duì)象的創(chuàng)建和依賴關(guān)系的維護(hù),交給Spring管理目代。

  • AOP編程的支持

    Spring提供面向切面編程屈梁,可以方便的實(shí)現(xiàn)對(duì)程序進(jìn)行權(quán)限攔截、運(yùn)行監(jiān)控等功能榛了。

  • 聲明式事務(wù)的支持

    只需要通過配置就可以完成對(duì)事務(wù)的管理在讶,而無需手動(dòng)編程。

  • 方便程序的測試

    Spring對(duì)Junit4支持霜大,可以通過注解方便的測試Spring程序真朗。

  • 方便集成各種優(yōu)秀框架

    Spring不排斥各種優(yōu)秀的開源框架,其內(nèi)部提供了對(duì)各種優(yōu)秀框架的直接支持(如:Struts僧诚、Hibernate遮婶、MyBatis等)蝗碎。

  • 降低JavaEE API的使用難度

    Spring對(duì)JavaEE開發(fā)中非常難用的一些API(JDBC、JavaMail旗扑、遠(yuǎn)程調(diào)用等)蹦骑,都提供了封裝,使這些API應(yīng)用難度大大降低臀防。

缺點(diǎn)

  • Spring明明一個(gè)很輕量級(jí)的框架眠菇,卻給人感覺大而全
  • Spring依賴反射,反射影響性能
  • 使用門檻升高袱衷,入門Spring需要較長時(shí)間

Spring有哪些應(yīng)用場景

應(yīng)用場景:JavaEE企業(yè)應(yīng)用開發(fā)捎废,包括SSH、SSM等

Spring價(jià)值

  • Spring是非侵入式的框架致燥,目標(biāo)是使應(yīng)用程序代碼對(duì)框架依賴最小化登疗;
  • Spring提供一個(gè)一致的編程模型,使應(yīng)用直接使用POJO開發(fā)嫌蚤,與運(yùn)行環(huán)境隔離開來辐益;
  • Spring推動(dòng)應(yīng)用設(shè)計(jì)風(fēng)格向面向?qū)ο蠛兔嫦蚪涌陂_發(fā)轉(zhuǎn)變,提高了代碼的重用性和可測試性脱吱;

Spring由哪些模塊組成智政?

Spring 總共大約有 20 個(gè)模塊, 由 1300 多個(gè)不同的文件構(gòu)成箱蝠。 而這些組件被分別整合在核心容器(Core Container) 续捂、 AOP(Aspect Oriented Programming)和設(shè)備支持(Instrmentation)數(shù)據(jù)訪問與集成(Data Access/Integeration) 宦搬、 Web谐腰、 消息(Messaging) 读串、 Test等 6 個(gè)模塊中惯悠。 以下是 Spring 5 的模塊結(jié)構(gòu)圖:

在這里插入圖片描述
  • spring core:提供了框架的基本組成部分躁锡,包括控制反轉(zhuǎn)(Inversion of Control装获,IOC)和依賴注入(Dependency Injection据过,DI)功能柔袁。
  • spring beans:提供了BeanFactory孝宗,是工廠模式的一個(gè)經(jīng)典實(shí)現(xiàn)差购,Spring將管理對(duì)象稱為Bean四瘫。
  • spring context:構(gòu)建于 core 封裝包基礎(chǔ)上的 context 封裝包,提供了一種框架式的對(duì)象訪問方法欲逃。
  • spring jdbc:提供了一個(gè)JDBC的抽象層找蜜,消除了煩瑣的JDBC編碼和數(shù)據(jù)庫廠商特有的錯(cuò)誤代碼解析, 用于簡化JDBC稳析。
  • spring aop:提供了面向切面的編程實(shí)現(xiàn)洗做,讓你可以自定義攔截器弓叛、切點(diǎn)等。
  • spring Web:提供了針對(duì) Web 開發(fā)的集成特性诚纸,例如文件上傳撰筷,利用 servlet listeners 進(jìn)行 ioc 容器初始化和針對(duì) Web 的 ApplicationContext。
  • spring test:主要為測試提供支持的畦徘,支持使用JUnit或TestNG對(duì)Spring組件進(jìn)行單元測試和集成測試毕籽。

Spring 框架中都用到了哪些設(shè)計(jì)模式?

  1. 工廠模式:BeanFactory就是簡單工廠模式的體現(xiàn)井辆,用來創(chuàng)建對(duì)象的實(shí)例关筒;
  2. 單例模式:Bean默認(rèn)為單例模式。
  3. 代理模式:Spring的AOP功能用到了JDK的動(dòng)態(tài)代理和CGLIB字節(jié)碼生成技術(shù)杯缺;
  4. 模板方法:用來解決代碼重復(fù)的問題蒸播。比如. RestTemplate, JmsTemplate, JpaTemplate。
  5. 觀察者模式:定義對(duì)象鍵一種一對(duì)多的依賴關(guān)系夺谁,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí)廉赔,所有依賴于它的對(duì)象都會(huì)得到通知被制動(dòng)更新,如Spring中l(wèi)istener的實(shí)現(xiàn)–ApplicationListener匾鸥。

詳細(xì)講解一下核心容器(spring context應(yīng)用上下文) 模塊

這是基本的Spring模塊蜡塌,提供spring 框架的基礎(chǔ)功能,BeanFactory 是 任何以spring為基礎(chǔ)的應(yīng)用的核心勿负。Spring 框架建立在此模塊之上馏艾,它使Spring成為一個(gè)容器。

Bean 工廠是工廠模式的一個(gè)實(shí)現(xiàn)奴愉,提供了控制反轉(zhuǎn)功能琅摩,用來把應(yīng)用的配置和依賴從真正的應(yīng)用代碼中分離。最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory 锭硼,它根據(jù)XML文件中的定義加載beans房资。該容器從XML 文件讀取配置元數(shù)據(jù)并用它去創(chuàng)建一個(gè)完全配置的系統(tǒng)或應(yīng)用。

Spring框架中有哪些不同類型的事件

Spring 提供了以下5種標(biāo)準(zhǔn)的事件:

  1. 上下文更新事件(ContextRefreshedEvent):在調(diào)用ConfigurableApplicationContext 接口中的refresh()方法時(shí)被觸發(fā)檀头。
  2. 上下文開始事件(ContextStartedEvent):當(dāng)容器調(diào)用ConfigurableApplicationContext的Start()方法開始/重新開始容器時(shí)觸發(fā)該事件轰异。
  3. 上下文停止事件(ContextStoppedEvent):當(dāng)容器調(diào)用ConfigurableApplicationContext的Stop()方法停止容器時(shí)觸發(fā)該事件。
  4. 上下文關(guān)閉事件(ContextClosedEvent):當(dāng)ApplicationContext被關(guān)閉時(shí)觸發(fā)該事件暑始。容器被關(guān)閉時(shí)搭独,其管理的所有單例Bean都被銷毀。
  5. 請(qǐng)求處理事件(RequestHandledEvent):在Web應(yīng)用中廊镜,當(dāng)一個(gè)http請(qǐng)求(request)結(jié)束觸發(fā)該事件牙肝。如果一個(gè)bean實(shí)現(xiàn)了ApplicationListener接口,當(dāng)一個(gè)ApplicationEvent 被發(fā)布以后,bean會(huì)自動(dòng)被通知配椭。

Spring 應(yīng)用程序有哪些不同組件虫溜?

Spring 應(yīng)用一般有以下組件:

  • 接口 - 定義功能。
  • Bean 類 - 它包含屬性颂郎,setter 和 getter 方法吼渡,函數(shù)等。
  • Bean 配置文件 - 包含類的信息以及如何配置它們乓序。
  • Spring 面向切面編程(AOP) - 提供面向切面編程的功能寺酪。
  • 用戶程序 - 它使用接口。

使用 Spring 有哪些方式替劈?

使用 Spring 有以下方式:

  • 作為一個(gè)成熟的 Spring Web 應(yīng)用程序寄雀。
  • 作為第三方 Web 框架,使用 Spring Frameworks 中間層陨献。
  • 作為企業(yè)級(jí) Java Bean盒犹,它可以包裝現(xiàn)有的 POJO(Plain Old Java Objects)。
  • 用于遠(yuǎn)程使用眨业。

Spring控制反轉(zhuǎn)(IOC)(13)

什么是Spring IOC 容器急膀?

控制反轉(zhuǎn)即IoC (Inversion of Control),它把傳統(tǒng)上由程序代碼直接操控的對(duì)象的調(diào)用權(quán)交給容器龄捡,通過容器來實(shí)現(xiàn)對(duì)象組件的裝配和管理卓嫂。所謂的“控制反轉(zhuǎn)”概念就是對(duì)組件對(duì)象控制權(quán)的轉(zhuǎn)移,從程序代碼本身轉(zhuǎn)移到了外部容器聘殖。

Spring IOC 負(fù)責(zé)創(chuàng)建對(duì)象晨雳,管理對(duì)象(通過依賴注入(DI),裝配對(duì)象奸腺,配置對(duì)象餐禁,并且管理這些對(duì)象的整個(gè)生命周期。

控制反轉(zhuǎn)(IoC)有什么作用

  • 管理對(duì)象的創(chuàng)建和依賴關(guān)系的維護(hù)突照。對(duì)象的創(chuàng)建并不是一件簡單的事帮非,在對(duì)象關(guān)系比較復(fù)雜時(shí),如果依賴關(guān)系需要程序猿來維護(hù)的話讹蘑,那是相當(dāng)頭疼的
  • 解耦末盔,由容器去維護(hù)具體的對(duì)象
  • 托管了類的產(chǎn)生過程,比如我們需要在類的產(chǎn)生過程中做一些處理衔肢,最直接的例子就是代理庄岖,如果有容器程序可以把這部分處理交給容器豁翎,應(yīng)用程序則無需去關(guān)心類是如何完成代理的

IOC的優(yōu)點(diǎn)是什么角骤?

  • IOC 或 依賴注入把應(yīng)用的代碼量降到最低。
  • 它使應(yīng)用容易測試,單元測試不再需要單例和JNDI查找機(jī)制邦尊。
  • 最小的代價(jià)和最小的侵入性使松散耦合得以實(shí)現(xiàn)背桐。
  • IOC容器支持加載服務(wù)時(shí)的餓漢式初始化和懶加載。

Spring IoC 的實(shí)現(xiàn)機(jī)制

Spring 中的 IoC 的實(shí)現(xiàn)原理就是工廠模式加反射機(jī)制蝉揍。

示例:

interface Fruit {
   public abstract void eat();
 }

class Apple implements Fruit {
    public void eat(){
        System.out.println("Apple");
    }
}

class Orange implements Fruit {
    public void eat(){
        System.out.println("Orange");
    }
}

class Factory {
    public static Fruit getInstance(String ClassName) {
        Fruit f=null;
        try {
            f=(Fruit)Class.forName(ClassName).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}

class Client {
    public static void main(String[] a) {
        Fruit f=Factory.getInstance("io.github.dunwu.spring.Apple");
        if(f!=null){
            f.eat();
        }
    }
}

Spring 的 IoC支持哪些功能

Spring 的 IoC 設(shè)計(jì)支持以下功能:

  • 依賴注入
  • 依賴檢查
  • 自動(dòng)裝配
  • 支持集合
  • 指定初始化方法和銷毀方法
  • 支持回調(diào)某些方法(但是需要實(shí)現(xiàn) Spring 接口链峭,略有侵入)

其中,最重要的就是依賴注入又沾,從 XML 的配置上說弊仪,即 ref 標(biāo)簽。對(duì)應(yīng) Spring RuntimeBeanReference 對(duì)象杖刷。

對(duì)于 IoC 來說励饵,最重要的就是容器。容器管理著 Bean 的生命周期滑燃,控制著 Bean 的依賴注入役听。

BeanFactory 和 ApplicationContext有什么區(qū)別?

BeanFactory和ApplicationContext是Spring的兩大核心接口表窘,都可以當(dāng)做Spring的容器典予。其中ApplicationContext是BeanFactory的子接口。

依賴關(guān)系

BeanFactory:是Spring里面最底層的接口乐严,包含了各種Bean的定義瘤袖,讀取bean配置文檔,管理bean的加載麦备、實(shí)例化孽椰,控制bean的生命周期,維護(hù)bean之間的依賴關(guān)系凛篙。

ApplicationContext接口作為BeanFactory的派生黍匾,除了提供BeanFactory所具有的功能外,還提供了更完整的框架功能:

  • 繼承MessageSource呛梆,因此支持國際化锐涯。
  • 統(tǒng)一的資源文件訪問方式。
  • 提供在監(jiān)聽器中注冊bean的事件填物。
  • 同時(shí)加載多個(gè)配置文件纹腌。
  • 載入多個(gè)(有繼承關(guān)系)上下文 ,使得每一個(gè)上下文都專注于一個(gè)特定的層次滞磺,比如應(yīng)用的web層升薯。

加載方式

BeanFactroy采用的是延遲加載形式來注入Bean的,即只有在使用到某個(gè)Bean時(shí)(調(diào)用getBean())击困,才對(duì)該Bean進(jìn)行加載實(shí)例化涎劈。這樣广凸,我們就不能發(fā)現(xiàn)一些存在的Spring的配置問題。如果Bean的某一個(gè)屬性沒有注入蛛枚,BeanFacotry加載后谅海,直至第一次使用調(diào)用getBean方法才會(huì)拋出異常。

ApplicationContext蹦浦,它是在容器啟動(dòng)時(shí)扭吁,一次性創(chuàng)建了所有的Bean。這樣盲镶,在容器啟動(dòng)時(shí)侥袜,我們就可以發(fā)現(xiàn)Spring中存在的配置錯(cuò)誤,這樣有利于檢查所依賴屬性是否注入溉贿。 ApplicationContext啟動(dòng)后預(yù)載入所有的單實(shí)例Bean系馆,通過預(yù)載入單實(shí)例bean ,確保當(dāng)你需要的時(shí)候,你就不用等待顽照,因?yàn)樗鼈円呀?jīng)創(chuàng)建好了由蘑。

相對(duì)于基本的BeanFactory,ApplicationContext 唯一的不足是占用內(nèi)存空間代兵。當(dāng)應(yīng)用程序配置Bean較多時(shí)尼酿,程序啟動(dòng)較慢。

創(chuàng)建方式

BeanFactory通常以編程的方式被創(chuàng)建植影,ApplicationContext還能以聲明的方式創(chuàng)建裳擎,如使用ContextLoader。

注冊方式

BeanFactory和ApplicationContext都支持BeanPostProcessor思币、BeanFactoryPostProcessor的使用鹿响,但兩者之間的區(qū)別是:BeanFactory需要手動(dòng)注冊,而ApplicationContext則是自動(dòng)注冊谷饿。

Spring 如何設(shè)計(jì)容器的惶我,BeanFactory和ApplicationContext的關(guān)系詳解

Spring 作者 Rod Johnson 設(shè)計(jì)了兩個(gè)接口用以表示容器。

  • BeanFactory
  • ApplicationContext

BeanFactory 簡單粗暴博投,可以理解為就是個(gè) HashMap绸贡,Key 是 BeanName,Value 是 Bean 實(shí)例毅哗。通常只提供注冊(put)听怕,獲取(get)這兩個(gè)功能虑绵。我們可以稱之為 “低級(jí)容器”尿瞭。

ApplicationContext 可以稱之為 “高級(jí)容器”。因?yàn)樗?BeanFactory 多了更多的功能翅睛。他繼承了多個(gè)接口声搁。因此具備了更多的功能鸣峭。例如資源的獲取,支持多種消息(例如 JSP tag 的支持)酥艳,對(duì) BeanFactory 多了工具級(jí)別的支持等待。所以你看他的名字爬骤,已經(jīng)不是 BeanFactory 之類的工廠了充石,而是 “應(yīng)用上下文”, 代表著整個(gè)大容器的所有功能霞玄。該接口定義了一個(gè) refresh 方法骤铃,此方法是所有閱讀 Spring 源碼的人的最熟悉的方法,用于刷新整個(gè)容器坷剧,即重新加載/刷新所有的 bean惰爬。

當(dāng)然,除了這兩個(gè)大接口惫企,還有其他的輔助接口撕瞧,這里就不介紹他們了。

BeanFactory和ApplicationContext的關(guān)系

為了更直觀的展示 “低級(jí)容器” 和 “高級(jí)容器” 的關(guān)系狞尔,這里通過常用的 ClassPathXmlApplicationContext 類來展示整個(gè)容器的層級(jí) UML 關(guān)系丛版。

img

有點(diǎn)復(fù)雜? 先不要慌偏序,我來解釋一下页畦。

最上面的是 BeanFactory,下面的 3 個(gè)綠色的研儒,都是功能擴(kuò)展接口豫缨,這里就不展開講。

看下面的隸屬 ApplicationContext 粉紅色的 “高級(jí)容器”端朵,依賴著 “低級(jí)容器”好芭,這里說的是依賴,不是繼承哦冲呢。他依賴著 “低級(jí)容器” 的 getBean 功能栓撞。而高級(jí)容器有更多的功能:支持不同的信息源頭,可以訪問文件資源碗硬,支持應(yīng)用事件(Observer 模式)瓤湘。

通常用戶看到的就是 “高級(jí)容器”。 但 BeanFactory 也非常夠用啦恩尾!

左邊灰色區(qū)域的是 “低級(jí)容器”弛说, 只負(fù)載加載 Bean,獲取 Bean翰意。容器其他的高級(jí)功能是沒有的木人。例如上圖畫的 refresh 刷新 Bean 工廠所有配置信柿,生命周期事件回調(diào)等。

小結(jié)

說了這么多醒第,不知道你有沒有理解Spring IoC渔嚷? 這里小結(jié)一下:IoC 在 Spring 里,只需要低級(jí)容器就可以實(shí)現(xiàn)稠曼,2 個(gè)步驟:

  1. 加載配置文件形病,解析成 BeanDefinition 放在 Map 里。
  2. 調(diào)用 getBean 的時(shí)候霞幅,從 BeanDefinition 所屬的 Map 里漠吻,拿出 Class 對(duì)象進(jìn)行實(shí)例化,同時(shí)司恳,如果有依賴關(guān)系途乃,將遞歸調(diào)用 getBean 方法 —— 完成依賴注入。

上面就是 Spring 低級(jí)容器(BeanFactory)的 IoC扔傅。

至于高級(jí)容器 ApplicationContext耍共,他包含了低級(jí)容器的功能,當(dāng)他執(zhí)行 refresh 模板方法的時(shí)候猎塞,將刷新整個(gè)容器的 Bean划提。同時(shí)其作為高級(jí)容器,包含了太多的功能邢享。一句話鹏往,他不僅僅是 IoC。他支持不同信息源頭骇塘,支持 BeanFactory 工具類伊履,支持層級(jí)容器,支持訪問文件資源款违,支持事件發(fā)布通知唐瀑,支持接口回調(diào)等等。

ApplicationContext通常的實(shí)現(xiàn)是什么插爹?

FileSystemXmlApplicationContext :此容器從一個(gè)XML文件中加載beans的定義哄辣,XML Bean 配置文件的全路徑名必須提供給它的構(gòu)造函數(shù)。

ClassPathXmlApplicationContext:此容器也從一個(gè)XML文件中加載beans的定義赠尾,這里力穗,你需要正確設(shè)置classpath因?yàn)檫@個(gè)容器將在classpath里找bean配置。

WebXmlApplicationContext:此容器加載一個(gè)XML文件气嫁,此文件定義了一個(gè)WEB應(yīng)用的所有bean当窗。

什么是Spring的依賴注入?

控制反轉(zhuǎn)IoC是一個(gè)很大的概念寸宵,可以用不同的方式來實(shí)現(xiàn)崖面。其主要實(shí)現(xiàn)方式有兩種:依賴注入和依賴查找

依賴注入:相對(duì)于IoC而言元咙,依賴注入(DI)更加準(zhǔn)確地描述了IoC的設(shè)計(jì)理念。所謂依賴注入(Dependency Injection)巫员,即組件之間的依賴關(guān)系由容器在應(yīng)用系統(tǒng)運(yùn)行期來決定庶香,也就是由容器動(dòng)態(tài)地將某種依賴關(guān)系的目標(biāo)對(duì)象實(shí)例注入到應(yīng)用系統(tǒng)中的各個(gè)關(guān)聯(lián)的組件之中。組件不做定位查詢简识,只提供普通的Java方法讓容器去決定依賴關(guān)系赶掖。

依賴注入的基本原則

依賴注入的基本原則是:應(yīng)用組件不應(yīng)該負(fù)責(zé)查找資源或者其他依賴的協(xié)作對(duì)象。配置對(duì)象的工作應(yīng)該由IoC容器負(fù)責(zé)财异,“查找資源”的邏輯應(yīng)該從應(yīng)用組件的代碼中抽取出來,交給IoC容器負(fù)責(zé)唱遭。容器全權(quán)負(fù)責(zé)組件的裝配戳寸,它會(huì)把符合依賴關(guān)系的對(duì)象通過屬性(JavaBean中的setter)或者是構(gòu)造器傳遞給需要的對(duì)象。

依賴注入有什么優(yōu)勢

依賴注入之所以更流行是因?yàn)樗且环N更可取的方式:讓容器全權(quán)負(fù)責(zé)依賴查詢拷泽,受管組件只需要暴露JavaBean的setter方法或者帶參數(shù)的構(gòu)造器或者接口疫鹊,使容器可以在初始化時(shí)組裝對(duì)象的依賴關(guān)系。其與依賴查找方式相比司致,主要優(yōu)勢為:

  • 查找定位操作與應(yīng)用代碼完全無關(guān)拆吆。
  • 不依賴于容器的API,可以很容易地在任何容器以外使用應(yīng)用對(duì)象脂矫。
  • 不需要特殊的接口枣耀,絕大多數(shù)對(duì)象可以做到完全不必依賴容器。

有哪些不同類型的依賴注入實(shí)現(xiàn)方式庭再?

依賴注入是時(shí)下最流行的IoC實(shí)現(xiàn)方式捞奕,依賴注入分為接口注入(Interface Injection),Setter方法注入(Setter Injection)和構(gòu)造器注入(Constructor Injection)三種方式拄轻。其中接口注入由于在靈活性和易用性比較差颅围,現(xiàn)在從Spring4開始已被廢棄。

構(gòu)造器依賴注入:構(gòu)造器依賴注入通過容器觸發(fā)一個(gè)類的構(gòu)造器來實(shí)現(xiàn)的恨搓,該類有一系列參數(shù)院促,每個(gè)參數(shù)代表一個(gè)對(duì)其他類的依賴。

Setter方法注入:Setter方法注入是容器通過調(diào)用無參構(gòu)造器或無參static工廠 方法實(shí)例化bean之后斧抱,調(diào)用該bean的setter方法常拓,即實(shí)現(xiàn)了基于setter的依賴注入。

構(gòu)造器依賴注入和 Setter方法注入的區(qū)別

構(gòu)造函數(shù)注入 setter 注入
沒有部分注入 有部分注入
不會(huì)覆蓋 setter 屬性 會(huì)覆蓋 setter 屬性
任意修改都會(huì)創(chuàng)建一個(gè)新實(shí)例 任意修改不會(huì)創(chuàng)建一個(gè)新實(shí)例
適用于設(shè)置很多屬性 適用于設(shè)置少量屬性

兩種依賴方式都可以使用辉浦,構(gòu)造器注入和Setter方法注入墩邀。最好的解決方案是用構(gòu)造器參數(shù)實(shí)現(xiàn)強(qiáng)制依賴,setter方法實(shí)現(xiàn)可選依賴盏浙。

Spring Beans(19)

什么是Spring beans眉睹?

Spring beans 是那些形成Spring應(yīng)用的主干的java對(duì)象荔茬。它們被Spring IOC容器初始化,裝配竹海,和管理慕蔚。這些beans通過容器中配置的元數(shù)據(jù)創(chuàng)建。比如斋配,以XML文件中 的形式定義孔飒。

一個(gè) Spring Bean 定義 包含什么?

一個(gè)Spring Bean 的定義包含容器必知的所有配置元數(shù)據(jù)艰争,包括如何創(chuàng)建一個(gè)bean坏瞄,它的生命周期詳情及它的依賴。

如何給Spring 容器提供配置元數(shù)據(jù)甩卓?Spring有幾種配置方式

這里有三種重要的方法給Spring 容器提供配置元數(shù)據(jù)鸠匀。

  • XML配置文件。
  • 基于注解的配置逾柿。
  • 基于java的配置缀棍。

Spring配置文件包含了哪些信息

Spring配置文件是個(gè)XML 文件,這個(gè)文件包含了類信息机错,描述了如何配置它們爬范,以及如何相互調(diào)用。

Spring基于xml注入bean的幾種方式

  1. Set方法注入弱匪;
  2. 構(gòu)造器注入:①通過index設(shè)置參數(shù)的位置青瀑;②通過type設(shè)置參數(shù)類型;
  3. 靜態(tài)工廠注入萧诫;
  4. 實(shí)例工廠狱窘;

你怎樣定義類的作用域?

當(dāng)定義一個(gè) 在Spring里财搁,我們還能給這個(gè)bean聲明一個(gè)作用域蘸炸。它可以通過bean 定義中的scope屬性來定義。如尖奔,當(dāng)Spring要在需要的時(shí)候每次生產(chǎn)一個(gè)新的bean實(shí)例搭儒,bean的scope屬性被指定為prototype。另一方面提茁,一個(gè)bean每次使用的時(shí)候必須返回同一個(gè)實(shí)例淹禾,這個(gè)bean的scope 屬性 必須設(shè)為 singleton。

解釋Spring支持的幾種bean的作用域

Spring框架支持以下五種bean的作用域:

  • singleton : bean在每個(gè)Spring ioc 容器中只有一個(gè)實(shí)例茴扁。
  • prototype:一個(gè)bean的定義可以有多個(gè)實(shí)例铃岔。
  • request:每次http請(qǐng)求都會(huì)創(chuàng)建一個(gè)bean,該作用域僅在基于web的Spring ApplicationContext情形下有效。
  • session:在一個(gè)HTTP Session中毁习,一個(gè)bean定義對(duì)應(yīng)一個(gè)實(shí)例智嚷。該作用域僅在基于web的Spring ApplicationContext情形下有效。
  • global-session:在一個(gè)全局的HTTP Session中纺且,一個(gè)bean定義對(duì)應(yīng)一個(gè)實(shí)例盏道。該作用域僅在基于web的Spring ApplicationContext情形下有效。

注意: 缺省的Spring bean 的作用域是Singleton载碌。使用 prototype 作用域需要慎重的思考猜嘱,因?yàn)轭l繁創(chuàng)建和銷毀 bean 會(huì)帶來很大的性能開銷。

Spring框架中的單例bean是線程安全的嗎嫁艇?

不是朗伶,Spring框架中的單例bean不是線程安全的。

spring 中的 bean 默認(rèn)是單例模式步咪,spring 框架并沒有對(duì)單例 bean 進(jìn)行多線程的封裝處理论皆。

實(shí)際上大部分時(shí)候 spring bean 無狀態(tài)的(比如 dao 類),所有某種程度上來說 bean 也是安全的歧斟,但如果 bean 有狀態(tài)的話(比如 view model 對(duì)象)纯丸,那就要開發(fā)者自己去保證線程安全了偏形,最簡單的就是改變 bean 的作用域静袖,把“singleton”變更為“prototype”,這樣請(qǐng)求 bean 相當(dāng)于 new Bean()了俊扭,所以就可以保證線程安全了队橙。

  • 有狀態(tài)就是有數(shù)據(jù)存儲(chǔ)功能。
  • 無狀態(tài)就是不會(huì)保存數(shù)據(jù)萨惑。

Spring如何處理線程并發(fā)問題捐康?

在一般情況下,只有無狀態(tài)的Bean才可以在多線程環(huán)境下共享庸蔼,在Spring中解总,絕大部分Bean都可以聲明為singleton作用域,因?yàn)镾pring對(duì)一些Bean中非線程安全狀態(tài)采用ThreadLocal進(jìn)行處理姐仅,解決線程安全問題花枫。

ThreadLocal和線程同步機(jī)制都是為了解決多線程中相同變量的訪問沖突問題。同步機(jī)制采用了“時(shí)間換空間”的方式掏膏,僅提供一份變量劳翰,不同的線程在訪問前需要獲取鎖,沒獲得鎖的線程則需要排隊(duì)馒疹。而ThreadLocal采用了“空間換時(shí)間”的方式佳簸。

ThreadLocal會(huì)為每一個(gè)線程提供一個(gè)獨(dú)立的變量副本,從而隔離了多個(gè)線程對(duì)數(shù)據(jù)的訪問沖突。因?yàn)槊恳粋€(gè)線程都擁有自己的變量副本蓖议,從而也就沒有必要對(duì)該變量進(jìn)行同步了。ThreadLocal提供了線程安全的共享對(duì)象贱鼻,在編寫多線程代碼時(shí)疯特,可以把不安全的變量封裝進(jìn)ThreadLocal哗魂。

解釋Spring框架中bean的生命周期

在傳統(tǒng)的Java應(yīng)用中,bean的生命周期很簡單漓雅。使用Java關(guān)鍵字new進(jìn)行bean實(shí)例化录别,然后該bean就可以使用了。一旦該bean不再被使用邻吞,則由Java自動(dòng)進(jìn)行垃圾回收组题。相比之下,Spring容器中的bean的生命周期就顯得相對(duì)復(fù)雜多了抱冷。正確理解Spring bean的生命周期非常重要崔列,因?yàn)槟慊蛟S要利用Spring提供的擴(kuò)展點(diǎn)來自定義bean的創(chuàng)建過程。下圖展示了bean裝載到Spring應(yīng)用上下文中的一個(gè)典型的生命周期過程旺遮。

img

bean在Spring容器中從創(chuàng)建到銷毀經(jīng)歷了若干階段赵讯,每一階段都可以針對(duì)Spring如何管理bean進(jìn)行個(gè)性化定制。

正如你所見耿眉,在bean準(zhǔn)備就緒之前边翼,bean工廠執(zhí)行了若干啟動(dòng)步驟。

我們對(duì)上圖進(jìn)行詳細(xì)描述:

Spring對(duì)bean進(jìn)行實(shí)例化鸣剪;

Spring將值和bean的引用注入到bean對(duì)應(yīng)的屬性中组底;

如果bean實(shí)現(xiàn)了BeanNameAware接口,Spring將bean的ID傳遞給setBean-Name()方法筐骇;

如果bean實(shí)現(xiàn)了BeanFactoryAware接口债鸡,Spring將調(diào)用setBeanFactory()方法,將BeanFactory容器實(shí)例傳入铛纬;

如果bean實(shí)現(xiàn)了ApplicationContextAware接口厌均,Spring將調(diào)用setApplicationContext()方法,將bean所在的應(yīng)用上下文的引用傳入進(jìn)來告唆;

如果bean實(shí)現(xiàn)了BeanPostProcessor接口棺弊,Spring將調(diào)用它們的post-ProcessBeforeInitialization()方法;

如果bean實(shí)現(xiàn)了InitializingBean接口悔详,Spring將調(diào)用它們的after-PropertiesSet()方法镊屎。類似地,如果bean使用initmethod聲明了初始化方法茄螃,該方法也會(huì)被調(diào)用缝驳;

如果bean實(shí)現(xiàn)了BeanPostProcessor接口,Spring將調(diào)用它們的post-ProcessAfterInitialization()方法;

此時(shí)用狱,bean已經(jīng)準(zhǔn)備就緒运怖,可以被應(yīng)用程序使用了,它們將一直駐留在應(yīng)用上下文中夏伊,直到該應(yīng)用上下文被銷毀摇展;

如果bean實(shí)現(xiàn)了DisposableBean接口,Spring將調(diào)用它的destroy()接口方法溺忧。同樣咏连,如果bean使用destroy-method聲明了銷毀方法,該方法也會(huì)被調(diào)用鲁森。

現(xiàn)在你已經(jīng)了解了如何創(chuàng)建和加載一個(gè)Spring容器祟滴。但是一個(gè)空的容器并沒有太大的價(jià)值,在你把東西放進(jìn)去之前歌溉,它里面什么都沒有垄懂。為了從Spring的DI(依賴注入)中受益,我們必須將應(yīng)用對(duì)象裝配進(jìn)Spring容器中痛垛。

哪些是重要的bean生命周期方法草慧? 你能重載它們嗎?

有兩個(gè)重要的bean 生命周期方法匙头,第一個(gè)是setup 漫谷, 它是在容器加載bean的時(shí)候被調(diào)用。第二個(gè)方法是 teardown 它是在容器卸載類的時(shí)候被調(diào)用乾胶。

bean 標(biāo)簽有兩個(gè)重要的屬性(init-method和destroy-method)抖剿。用它們你可以自己定制初始化和注銷方法朽寞。它們也有相應(yīng)的注解(@PostConstruct和@PreDestroy)识窿。

什么是Spring的內(nèi)部bean?什么是Spring inner beans脑融?

在Spring框架中喻频,當(dāng)一個(gè)bean僅被用作另一個(gè)bean的屬性時(shí),它能被聲明為一個(gè)內(nèi)部bean肘迎。內(nèi)部bean可以用setter注入“屬性”和構(gòu)造方法注入“構(gòu)造參數(shù)”的方式來實(shí)現(xiàn)甥温,內(nèi)部bean通常是匿名的,它們的Scope一般是prototype妓布。

在 Spring中如何注入一個(gè)java集合姻蚓?

Spring提供以下幾種集合的配置元素:

類型用于注入一列值,允許有相同的值匣沼。

類型用于注入一組值狰挡,不允許有相同的值。

類型用于注入一組鍵值對(duì),鍵和值都可以為任意類型加叁。

類型用于注入一組鍵值對(duì)倦沧,鍵和值都只能為String類型。

什么是bean裝配它匕?

裝配展融,或bean 裝配是指在Spring 容器中把bean組裝到一起,前提是容器需要知道bean的依賴關(guān)系豫柬,如何通過依賴注入來把它們裝配到一起告希。

什么是bean的自動(dòng)裝配?

在Spring框架中烧给,在配置文件中設(shè)定bean的依賴關(guān)系是一個(gè)很好的機(jī)制暂雹,Spring 容器能夠自動(dòng)裝配相互合作的bean,這意味著容器不需要和配置创夜,能通過Bean工廠自動(dòng)處理bean之間的協(xié)作杭跪。這意味著 Spring可以通過向Bean Factory中注入的方式自動(dòng)搞定bean之間的依賴關(guān)系。自動(dòng)裝配可以設(shè)置在每個(gè)bean上驰吓,也可以設(shè)定在特定的bean上涧尿。

解釋不同方式的自動(dòng)裝配,spring 自動(dòng)裝配 bean 有哪些方式檬贰?

在spring中姑廉,對(duì)象無需自己查找或創(chuàng)建與其關(guān)聯(lián)的其他對(duì)象,由容器負(fù)責(zé)把需要相互協(xié)作的對(duì)象引用賦予各個(gè)對(duì)象翁涤,使用autowire來配置自動(dòng)裝載模式桥言。

在Spring框架xml配置中共有5種自動(dòng)裝配:

  • no:默認(rèn)的方式是不進(jìn)行自動(dòng)裝配的,通過手工設(shè)置ref屬性來進(jìn)行裝配bean葵礼。
  • byName:通過bean的名稱進(jìn)行自動(dòng)裝配号阿,如果一個(gè)bean的 property 與另一bean 的name 相同,就進(jìn)行自動(dòng)裝配鸳粉。
  • byType:通過參數(shù)的數(shù)據(jù)類型進(jìn)行自動(dòng)裝配扔涧。
  • constructor:利用構(gòu)造函數(shù)進(jìn)行裝配,并且構(gòu)造函數(shù)的參數(shù)通過byType進(jìn)行裝配届谈。
  • autodetect:自動(dòng)探測枯夜,如果有構(gòu)造方法,通過 construct的方式自動(dòng)裝配艰山,否則使用 byType的方式自動(dòng)裝配湖雹。

使用@Autowired注解自動(dòng)裝配的過程是怎樣的?

使用@Autowired注解來自動(dòng)裝配指定的bean曙搬。在使用@Autowired注解之前需要在Spring配置文件進(jìn)行配置摔吏,<context:annotation-config />汤踏。

在啟動(dòng)spring IoC時(shí),容器自動(dòng)裝載了一個(gè)AutowiredAnnotationBeanPostProcessor后置處理器舔腾,當(dāng)容器掃描到@Autowied溪胶、@Resource或@Inject時(shí),就會(huì)在IoC容器自動(dòng)查找需要的bean稳诚,并裝配給該對(duì)象的屬性哗脖。在使用@Autowired時(shí),首先在容器中查詢對(duì)應(yīng)類型的bean:

  • 如果查詢結(jié)果剛好為一個(gè)扳还,就將該bean裝配給@Autowired指定的數(shù)據(jù)才避;
  • 如果查詢的結(jié)果不止一個(gè),那么@Autowired會(huì)根據(jù)名稱來查找氨距;
  • 如果上述查找的結(jié)果為空桑逝,那么會(huì)拋出異常。解決方法時(shí)俏让,使用required=false楞遏。

自動(dòng)裝配有哪些局限性?

自動(dòng)裝配的局限性是:

重寫:你仍需用 和 配置來定義依賴首昔,意味著總要重寫自動(dòng)裝配寡喝。

基本數(shù)據(jù)類型:你不能自動(dòng)裝配簡單的屬性,如基本數(shù)據(jù)類型勒奇,String字符串预鬓,和類。

模糊特性:自動(dòng)裝配不如顯式裝配精確赊颠,如果有可能格二,建議使用顯式裝配。

你可以在Spring中注入一個(gè)null 和一個(gè)空字符串嗎竣蹦?

可以顶猜。

Spring注解(8)

什么是基于Java的Spring注解配置? 給一些注解的例子

基于Java的配置,允許你在少量的Java注解的幫助下草添,進(jìn)行你的大部分Spring配置而非通過XML文件驶兜。

以@Configuration 注解為例扼仲,它用來標(biāo)記類可以當(dāng)做一個(gè)bean的定義远寸,被Spring IOC容器使用。

另一個(gè)例子是@Bean注解屠凶,它表示此方法將要返回一個(gè)對(duì)象驰后,作為一個(gè)bean注冊進(jìn)Spring應(yīng)用上下文。

@Configuration
public class StudentConfig {
    @Bean
    public StudentBean myStudent() {
        return new StudentBean();
    }
}

怎樣開啟注解裝配矗愧?

注解裝配在默認(rèn)情況下是不開啟的灶芝,為了使用注解裝配郑原,我們必須在Spring配置文件中配置 <context:annotation-config/>元素。

@Component, @Controller, @Repository, @Service 有何區(qū)別夜涕?

@Component:這將 java 類標(biāo)記為 bean犯犁。它是任何 Spring 管理組件的通用構(gòu)造型。spring 的組件掃描機(jī)制現(xiàn)在可以將其拾取并將其拉入應(yīng)用程序環(huán)境中女器。

@Controller:這將一個(gè)類標(biāo)記為 Spring Web MVC 控制器酸役。標(biāo)有它的 Bean 會(huì)自動(dòng)導(dǎo)入到 IoC 容器中。

@Service:此注解是組件注解的特化驾胆。它不會(huì)對(duì) @Component 注解提供任何其他行為涣澡。您可以在服務(wù)層類中使用 @Service 而不是 @Component,因?yàn)樗愿玫姆绞街付艘鈭D丧诺。

@Repository:這個(gè)注解是具有類似用途和功能的 @Component 注解的特化入桂。它為 DAO 提供了額外的好處。它將 DAO 導(dǎo)入 IoC 容器驳阎,并使未經(jīng)檢查的異常有資格轉(zhuǎn)換為 Spring DataAccessException抗愁。

@Required 注解有什么作用

這個(gè)注解表明bean的屬性必須在配置的時(shí)候設(shè)置,通過一個(gè)bean定義的顯式的屬性值或通過自動(dòng)裝配呵晚,若@Required注解的bean屬性未被設(shè)置驹愚,容器將拋出BeanInitializationException。示例:

public class Employee {
    private String name;
    @Required
    public void setName(String name){
        this.name=name;
    }
    public string getName(){
        return name;
    }
}

@Autowired 注解有什么作用

@Autowired默認(rèn)是按照類型裝配注入的劣纲,默認(rèn)情況下它要求依賴對(duì)象必須存在(可以設(shè)置它required屬性為false)逢捺。@Autowired 注解提供了更細(xì)粒度的控制,包括在何處以及如何完成自動(dòng)裝配癞季。它的用法和@Required一樣劫瞳,修飾setter方法、構(gòu)造器绷柒、屬性或者具有任意名稱和/或多個(gè)參數(shù)的PN方法志于。

public class Employee {
    private String name;
    @Autowired
    public void setName(String name) {
        this.name=name;
    }
    public string getName(){
        return name;
    }
}

@Autowired和@Resource之間的區(qū)別

@Autowired可用于:構(gòu)造函數(shù)、成員變量废睦、Setter方法

@Autowired和@Resource之間的區(qū)別

  • @Autowired默認(rèn)是按照類型裝配注入的伺绽,默認(rèn)情況下它要求依賴對(duì)象必須存在(可以設(shè)置它required屬性為false)。
  • @Resource默認(rèn)是按照名稱來裝配注入的嗜湃,只有當(dāng)找不到與名稱匹配的bean才會(huì)按照類型來裝配注入奈应。

@Qualifier 注解有什么作用

當(dāng)您創(chuàng)建多個(gè)相同類型的 bean 并希望僅使用屬性裝配其中一個(gè) bean 時(shí),您可以使用@Qualifier 注解和 @Autowired 通過指定應(yīng)該裝配哪個(gè)確切的 bean 來消除歧義购披。

@RequestMapping 注解有什么用杖挣?

@RequestMapping 注解用于將特定 HTTP 請(qǐng)求方法映射到將處理相應(yīng)請(qǐng)求的控制器中的特定類/方法。此注釋可應(yīng)用于兩個(gè)級(jí)別:

  • 類級(jí)別:映射請(qǐng)求的 URL
  • 方法級(jí)別:映射 URL 以及 HTTP 請(qǐng)求方法

Spring數(shù)據(jù)訪問(14)

解釋對(duì)象/關(guān)系映射集成模塊

Spring 通過提供ORM模塊刚陡,支持我們在直接JDBC之上使用一個(gè)對(duì)象/關(guān)系映射映射(ORM)工具惩妇,Spring 支持集成主流的ORM框架株汉,如Hiberate,JDO和 iBATIS歌殃,JPA乔妈,TopLink,JDO氓皱,OJB 褒翰。Spring的事務(wù)管理同樣支持以上所有ORM框架及JDBC。

在Spring框架中如何更有效地使用JDBC匀泊?

使用Spring JDBC 框架优训,資源管理和錯(cuò)誤處理的代價(jià)都會(huì)被減輕。所以開發(fā)者只需寫statements 和 queries從數(shù)據(jù)存取數(shù)據(jù)各聘,JDBC也可以在Spring框架提供的模板類的幫助下更有效地被使用揣非,這個(gè)模板叫JdbcTemplate

解釋JDBC抽象和DAO模塊

通過使用JDBC抽象和DAO模塊,保證數(shù)據(jù)庫代碼的簡潔躲因,并能避免數(shù)據(jù)庫資源錯(cuò)誤關(guān)閉導(dǎo)致的問題早敬,它在各種不同的數(shù)據(jù)庫的錯(cuò)誤信息之上,提供了一個(gè)統(tǒng)一的異常訪問層大脉。它還利用Spring的AOP 模塊給Spring應(yīng)用中的對(duì)象提供事務(wù)管理服務(wù)搞监。

spring DAO 有什么用?

Spring DAO(數(shù)據(jù)訪問對(duì)象) 使得 JDBC镰矿,Hibernate 或 JDO 這樣的數(shù)據(jù)訪問技術(shù)更容易以一種統(tǒng)一的方式工作琐驴。這使得用戶容易在持久性技術(shù)之間切換。它還允許您在編寫代碼時(shí)秤标,無需考慮捕獲每種技術(shù)不同的異常绝淡。

spring JDBC API 中存在哪些類?

JdbcTemplate

SimpleJdbcTemplate

NamedParameterJdbcTemplate

SimpleJdbcInsert

SimpleJdbcCall

JdbcTemplate是什么

JdbcTemplate 類提供了很多便利的方法解決諸如把數(shù)據(jù)庫數(shù)據(jù)轉(zhuǎn)變成基本數(shù)據(jù)類型或?qū)ο蟛越瑘?zhí)行寫好的或可調(diào)用的數(shù)據(jù)庫操作語句牢酵,提供自定義的數(shù)據(jù)錯(cuò)誤處理。

使用Spring通過什么方式訪問Hibernate衙猪?使用 Spring 訪問 Hibernate 的方法有哪些馍乙?

在Spring中有兩種方式訪問Hibernate:

  • 使用 Hibernate 模板和回調(diào)進(jìn)行控制反轉(zhuǎn)
  • 擴(kuò)展 HibernateDAOSupport 并應(yīng)用 AOP 攔截器節(jié)點(diǎn)

如何通過HibernateDaoSupport將Spring和Hibernate結(jié)合起來?

用Spring的 SessionFactory 調(diào)用 LocalSessionFactory垫释。集成過程分三步:

  • 配置the Hibernate SessionFactory
  • 繼承HibernateDaoSupport實(shí)現(xiàn)一個(gè)DAO
  • 在AOP支持的事務(wù)中裝配

Spring支持的事務(wù)管理類型丝格, spring 事務(wù)實(shí)現(xiàn)方式有哪些?

Spring支持兩種類型的事務(wù)管理:

編程式事務(wù)管理:這意味你通過編程的方式管理事務(wù)饶号,給你帶來極大的靈活性铁追,但是難維護(hù)。

聲明式事務(wù)管理:這意味著你可以將業(yè)務(wù)代碼和事務(wù)管理分離茫船,你只需用注解和XML配置來管理事務(wù)琅束。

Spring事務(wù)的實(shí)現(xiàn)方式和實(shí)現(xiàn)原理

Spring事務(wù)的本質(zhì)其實(shí)就是數(shù)據(jù)庫對(duì)事務(wù)的支持,沒有數(shù)據(jù)庫的事務(wù)支持算谈,spring是無法提供事務(wù)功能的涩禀。真正的數(shù)據(jù)庫層的事務(wù)提交和回滾是通過binlog或者redo log實(shí)現(xiàn)的。

說一下Spring的事務(wù)傳播行為

spring事務(wù)的傳播行為說的是然眼,當(dāng)多個(gè)事務(wù)同時(shí)存在的時(shí)候艾船,spring如何處理這些事務(wù)的行為。

① PROPAGATION_REQUIRED:如果當(dāng)前沒有事務(wù)高每,就創(chuàng)建一個(gè)新事務(wù)屿岂,如果當(dāng)前存在事務(wù),就加入該事務(wù)鲸匿,該設(shè)置是最常用的設(shè)置爷怀。

② PROPAGATION_SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前存在事務(wù)带欢,就加入該事務(wù)运授,如果當(dāng)前不存在事務(wù),就以非事務(wù)執(zhí)行乔煞。

③ PROPAGATION_MANDATORY:支持當(dāng)前事務(wù)吁朦,如果當(dāng)前存在事務(wù),就加入該事務(wù)渡贾,如果當(dāng)前不存在事務(wù)逗宜,就拋出異常。

④ PROPAGATION_REQUIRES_NEW:創(chuàng)建新事務(wù)空骚,無論當(dāng)前存不存在事務(wù)锦溪,都創(chuàng)建新事務(wù)。

⑤ PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作府怯,如果當(dāng)前存在事務(wù)刻诊,就把當(dāng)前事務(wù)掛起。

⑥ PROPAGATION_NEVER:以非事務(wù)方式執(zhí)行牺丙,如果當(dāng)前存在事務(wù)则涯,則拋出異常。

⑦ PROPAGATION_NESTED:如果當(dāng)前存在事務(wù)冲簿,則在嵌套事務(wù)內(nèi)執(zhí)行粟判。如果當(dāng)前沒有事務(wù),則按REQUIRED屬性執(zhí)行峦剔。

說一下 spring 的事務(wù)隔離档礁?

spring 有五大隔離級(jí)別,默認(rèn)值為 ISOLATION_DEFAULT(使用數(shù)據(jù)庫的設(shè)置)吝沫,其他四個(gè)隔離級(jí)別和數(shù)據(jù)庫的隔離級(jí)別一致:

  1. ISOLATION_DEFAULT:用底層數(shù)據(jù)庫的設(shè)置隔離級(jí)別呻澜,數(shù)據(jù)庫設(shè)置的是什么我就用什么递礼;
  2. ISOLATION_READ_UNCOMMITTED:未提交讀,最低隔離級(jí)別羹幸、事務(wù)未提交前脊髓,就可被其他事務(wù)讀取(會(huì)出現(xiàn)幻讀栅受、臟讀将硝、不可重復(fù)讀);
  3. ISOLATION_READ_COMMITTED:提交讀屏镊,一個(gè)事務(wù)提交后才能被其他事務(wù)讀取到(會(huì)造成幻讀依疼、不可重復(fù)讀),SQL server 的默認(rèn)級(jí)別而芥;
  4. ISOLATION_REPEATABLE_READ:可重復(fù)讀律罢,保證多次讀取同一個(gè)數(shù)據(jù)時(shí),其值都和事務(wù)開始時(shí)候的內(nèi)容是一致蔚出,禁止讀取到別的事務(wù)未提交的數(shù)據(jù)(會(huì)造成幻讀)弟翘,MySQL 的默認(rèn)級(jí)別;
  5. ISOLATION_SERIALIZABLE:序列化骄酗,代價(jià)最高最可靠的隔離級(jí)別稀余,該隔離級(jí)別能防止臟讀、不可重復(fù)讀趋翻、幻讀睛琳。

臟讀 :表示一個(gè)事務(wù)能夠讀取另一個(gè)事務(wù)中還未提交的數(shù)據(jù)。比如踏烙,某個(gè)事務(wù)嘗試插入記錄 A师骗,此時(shí)該事務(wù)還未提交,然后另一個(gè)事務(wù)嘗試讀取到了記錄 A讨惩。

不可重復(fù)讀 :是指在一個(gè)事務(wù)內(nèi)辟癌,多次讀同一數(shù)據(jù)。

幻讀 :指同一個(gè)事務(wù)內(nèi)多次查詢返回的結(jié)果集不一樣荐捻。比如同一個(gè)事務(wù) A 第一次查詢時(shí)候有 n 條記錄黍少,但是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產(chǎn)生了幻覺处面。發(fā)生幻讀的原因也是另外一個(gè)事務(wù)新增或者刪除或者修改了第一個(gè)事務(wù)結(jié)果集里面的數(shù)據(jù)厂置,同一個(gè)記錄的數(shù)據(jù)內(nèi)容被修改了,所有數(shù)據(jù)行的記錄就變多或者變少了魂角。

Spring框架的事務(wù)管理有哪些優(yōu)點(diǎn)昵济?

  • 為不同的事務(wù)API 如 JTA,JDBC,Hibernate访忿,JPA 和JDO瞧栗,提供一個(gè)不變的編程模式。
  • 為編程式事務(wù)管理提供了一套簡單的API而不是一些復(fù)雜的事務(wù)API
  • 支持聲明式事務(wù)管理醉顽。
  • 和Spring各種數(shù)據(jù)訪問抽象層很好得集成沼溜。

你更傾向用那種事務(wù)管理類型平挑?

大多數(shù)Spring框架的用戶選擇聲明式事務(wù)管理游添,因?yàn)樗鼘?duì)應(yīng)用代碼的影響最小,因此更符合一個(gè)無侵入的輕量級(jí)容器的思想通熄。聲明式事務(wù)管理要優(yōu)于編程式事務(wù)管理唆涝,雖然比編程式事務(wù)管理(這種方式允許你通過代碼控制事務(wù))少了一點(diǎn)靈活性。唯一不足地方是唇辨,最細(xì)粒度只能作用到方法級(jí)別廊酣,無法做到像編程式事務(wù)那樣可以作用到代碼塊級(jí)別。

Spring面向切面編程(AOP)(13)

什么是AOP

OOP(Object-Oriented Programming)面向?qū)ο缶幊躺兔叮试S開發(fā)者定義縱向的關(guān)系亡驰,但并適用于定義橫向的關(guān)系,導(dǎo)致了大量代碼的重復(fù)饿幅,而不利于各個(gè)模塊的重用凡辱。

AOP(Aspect-Oriented Programming),一般稱為面向切面編程栗恩,作為面向?qū)ο蟮囊环N補(bǔ)充透乾,用于將那些與業(yè)務(wù)無關(guān),但卻對(duì)多個(gè)對(duì)象產(chǎn)生影響的公共行為和邏輯磕秤,抽取并封裝為一個(gè)可重用的模塊乳乌,這個(gè)模塊被命名為“切面”(Aspect),減少系統(tǒng)中的重復(fù)代碼市咆,降低了模塊間的耦合度汉操,同時(shí)提高了系統(tǒng)的可維護(hù)性∶衫迹可用于權(quán)限認(rèn)證磷瘤、日志、事務(wù)處理等癞己。

Spring AOP and AspectJ AOP 有什么區(qū)別膀斋?AOP 有哪些實(shí)現(xiàn)方式?

AOP實(shí)現(xiàn)的關(guān)鍵在于 代理模式痹雅,AOP代理主要分為靜態(tài)代理和動(dòng)態(tài)代理仰担。靜態(tài)代理的代表為AspectJ;動(dòng)態(tài)代理則以Spring AOP為代表。

(1)AspectJ是靜態(tài)代理的增強(qiáng)摔蓝,所謂靜態(tài)代理赂苗,就是AOP框架會(huì)在編譯階段生成AOP代理類,因此也稱為編譯時(shí)增強(qiáng)贮尉,他會(huì)在編譯階段將AspectJ(切面)織入到Java字節(jié)碼中拌滋,運(yùn)行的時(shí)候就是增強(qiáng)之后的AOP對(duì)象。

(2)Spring AOP使用的動(dòng)態(tài)代理猜谚,所謂的動(dòng)態(tài)代理就是說AOP框架不會(huì)去修改字節(jié)碼败砂,而是每次運(yùn)行時(shí)在內(nèi)存中臨時(shí)為方法生成一個(gè)AOP對(duì)象,這個(gè)AOP對(duì)象包含了目標(biāo)對(duì)象的全部方法魏铅,并且在特定的切點(diǎn)做了增強(qiáng)處理昌犹,并回調(diào)原對(duì)象的方法。

JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理的區(qū)別

Spring AOP中的動(dòng)態(tài)代理主要有兩種方式览芳,JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理:

  • JDK動(dòng)態(tài)代理只提供接口的代理斜姥,不支持類的代理。核心InvocationHandler接口和Proxy類沧竟,InvocationHandler 通過invoke()方法反射來調(diào)用目標(biāo)類中的代碼铸敏,動(dòng)態(tài)地將橫切邏輯和業(yè)務(wù)編織在一起;接著悟泵,Proxy利用 InvocationHandler動(dòng)態(tài)創(chuàng)建一個(gè)符合某一接口的的實(shí)例, 生成目標(biāo)類的代理對(duì)象杈笔。
  • 如果代理類沒有實(shí)現(xiàn) InvocationHandler 接口,那么Spring AOP會(huì)選擇使用CGLIB來動(dòng)態(tài)代理目標(biāo)類魁袜。CGLIB(Code Generation Library)桩撮,是一個(gè)代碼生成的類庫,可以在運(yùn)行時(shí)動(dòng)態(tài)的生成指定類的一個(gè)子類對(duì)象峰弹,并覆蓋其中特定方法并添加增強(qiáng)代碼店量,從而實(shí)現(xiàn)AOP。CGLIB是通過繼承的方式做的動(dòng)態(tài)代理鞠呈,因此如果某個(gè)類被標(biāo)記為final融师,那么它是無法使用CGLIB做動(dòng)態(tài)代理的。

靜態(tài)代理與動(dòng)態(tài)代理區(qū)別在于生成AOP代理對(duì)象的時(shí)機(jī)不同蚁吝,相對(duì)來說AspectJ的靜態(tài)代理方式具有更好的性能旱爆,但是AspectJ需要特定的編譯器進(jìn)行處理,而Spring AOP則無需特定的編譯器處理窘茁。

InvocationHandler 的 invoke(Object proxy,Method method,Object[] args):proxy是最終生成的代理實(shí)例; method 是被代理目標(biāo)實(shí)例的某個(gè)具體方法; args 是被代理目標(biāo)實(shí)例某個(gè)方法的具體入?yún)? 在方法反射調(diào)用時(shí)使用怀伦。

如何理解 Spring 中的代理?

將 Advice 應(yīng)用于目標(biāo)對(duì)象后創(chuàng)建的對(duì)象稱為代理山林。在客戶端對(duì)象的情況下房待,目標(biāo)對(duì)象和代理對(duì)象是相同的。

Advice + Target Object = Proxy

解釋一下Spring AOP里面的幾個(gè)名詞

(1)切面(Aspect):切面是通知和切點(diǎn)的結(jié)合。通知和切點(diǎn)共同定義了切面的全部內(nèi)容桑孩。 在Spring AOP中拜鹤,切面可以使用通用類(基于模式的風(fēng)格) 或者在普通類中以 @AspectJ 注解來實(shí)現(xiàn)。

(2)連接點(diǎn)(Join point):指方法流椒,在Spring AOP中敏簿,一個(gè)連接點(diǎn) 總是 代表一個(gè)方法的執(zhí)行。 應(yīng)用可能有數(shù)以千計(jì)的時(shí)機(jī)應(yīng)用通知宣虾。這些時(shí)機(jī)被稱為連接點(diǎn)惯裕。連接點(diǎn)是在應(yīng)用執(zhí)行過程中能夠插入切面的一個(gè)點(diǎn)。這個(gè)點(diǎn)可以是調(diào)用方法時(shí)安岂、拋出異常時(shí)轻猖、甚至修改一個(gè)字段時(shí)帆吻。切面代碼可以利用這些點(diǎn)插入到應(yīng)用的正常流程之中域那,并添加新的行為。

(3)通知(Advice):在AOP術(shù)語中猜煮,切面的工作被稱為通知次员。

(4)切入點(diǎn)(Pointcut):切點(diǎn)的定義會(huì)匹配通知所要織入的一個(gè)或多個(gè)連接點(diǎn)。我們通常使用明確的類和方法名稱王带,或是利用正則表達(dá)式定義所匹配的類和方法名稱來指定這些切點(diǎn)淑蔚。

(5)引入(Introduction):引入允許我們向現(xiàn)有類添加新方法或?qū)傩浴?/p>

(6)目標(biāo)對(duì)象(Target Object): 被一個(gè)或者多個(gè)切面(aspect)所通知(advise)的對(duì)象。它通常是一個(gè)代理對(duì)象愕撰。也有人把它叫做 被通知(adviced) 對(duì)象刹衫。 既然Spring AOP是通過運(yùn)行時(shí)代理實(shí)現(xiàn)的,這個(gè)對(duì)象永遠(yuǎn)是一個(gè) 被代理(proxied) 對(duì)象搞挣。

(7)織入(Weaving):織入是把切面應(yīng)用到目標(biāo)對(duì)象并創(chuàng)建新的代理對(duì)象的過程带迟。在目標(biāo)對(duì)象的生命周期里有多少個(gè)點(diǎn)可以進(jìn)行織入:

  • 編譯期:切面在目標(biāo)類編譯時(shí)被織入。AspectJ的織入編譯器是以這種方式織入切面的囱桨。
  • 類加載期:切面在目標(biāo)類加載到JVM時(shí)被織入仓犬。需要特殊的類加載器,它可以在目標(biāo)類被引入應(yīng)用之前增強(qiáng)該目標(biāo)類的字節(jié)碼舍肠。AspectJ5的加載時(shí)織入就支持以這種方式織入切面搀继。
  • 運(yùn)行期:切面在應(yīng)用運(yùn)行的某個(gè)時(shí)刻被織入。一般情況下翠语,在織入切面時(shí)叽躯,AOP容器會(huì)為目標(biāo)對(duì)象動(dòng)態(tài)地創(chuàng)建一個(gè)代理對(duì)象。SpringAOP就是以這種方式織入切面肌括。

Spring在運(yùn)行時(shí)通知對(duì)象

通過在代理類中包裹切面点骑,Spring在運(yùn)行期把切面織入到Spring管理的bean中。代理封裝了目標(biāo)類,并攔截被通知方法的調(diào)用畔况,再把調(diào)用轉(zhuǎn)發(fā)給真正的目標(biāo)bean鲸鹦。當(dāng)代理攔截到方法調(diào)用時(shí),在調(diào)用目標(biāo)bean方法之前跷跪,會(huì)執(zhí)行切面邏輯馋嗜。

直到應(yīng)用需要被代理的bean時(shí),Spring才創(chuàng)建代理對(duì)象吵瞻。如果使用的是ApplicationContext的話葛菇,在ApplicationContext從BeanFactory中加載所有bean的時(shí)候,Spring才會(huì)創(chuàng)建被代理的對(duì)象橡羞。因?yàn)镾pring運(yùn)行時(shí)才創(chuàng)建代理對(duì)象眯停,所以我們不需要特殊的編譯器來織入SpringAOP的切面。

Spring只支持方法級(jí)別的連接點(diǎn)

因?yàn)镾pring基于動(dòng)態(tài)代理卿泽,所以Spring只支持方法連接點(diǎn)莺债。Spring缺少對(duì)字段連接點(diǎn)的支持,而且它不支持構(gòu)造器連接點(diǎn)签夭。方法之外的連接點(diǎn)攔截功能齐邦,我們可以利用Aspect來補(bǔ)充。

在Spring AOP 中第租,關(guān)注點(diǎn)和橫切關(guān)注的區(qū)別是什么措拇?在 spring aop 中 concern 和 cross-cutting concern 的不同之處

關(guān)注點(diǎn)(concern)是應(yīng)用中一個(gè)模塊的行為,一個(gè)關(guān)注點(diǎn)可能會(huì)被定義成一個(gè)我們想實(shí)現(xiàn)的一個(gè)功能慎宾。

橫切關(guān)注點(diǎn)(cross-cutting concern)是一個(gè)關(guān)注點(diǎn)丐吓,此關(guān)注點(diǎn)是整個(gè)應(yīng)用都會(huì)使用的功能,并影響整個(gè)應(yīng)用趟据,比如日志券犁,安全和數(shù)據(jù)傳輸,幾乎應(yīng)用的每個(gè)模塊都需要的功能之宿。因此這些都屬于橫切關(guān)注點(diǎn)族操。

Spring通知有哪些類型?

在AOP術(shù)語中比被,切面的工作被稱為通知章姓,實(shí)際上是程序執(zhí)行時(shí)要通過SpringAOP框架觸發(fā)的代碼段备籽。

Spring切面可以應(yīng)用5種類型的通知:

  1. 前置通知(Before):在目標(biāo)方法被調(diào)用之前調(diào)用通知功能;
  2. 后置通知(After):在目標(biāo)方法完成之后調(diào)用通知,此時(shí)不會(huì)關(guān)心方法的輸出是什么泞莉;
  3. 返回通知(After-returning ):在目標(biāo)方法成功執(zhí)行之后調(diào)用通知旁钧;
  4. 異常通知(After-throwing):在目標(biāo)方法拋出異常后調(diào)用通知具温;
  5. 環(huán)繞通知(Around):通知包裹了被通知的方法硅则,在被通知的方法調(diào)用之前和調(diào)用之后執(zhí)行自定義的行為冒掌。

同一個(gè)aspect,不同advice的執(zhí)行順序:

①?zèng)]有異常情況下的執(zhí)行順序:

around before advice
before advice
target method 執(zhí)行
around after advice
after advice
afterReturning

②有異常情況下的執(zhí)行順序:

around before advice
before advice
target method 執(zhí)行
around after advice
after advice
afterThrowing:異常發(fā)生
java.lang.RuntimeException: 異常發(fā)生

什么是切面 Aspect蹲盘?

aspect 由 pointcount 和 advice 組成股毫,切面是通知和切點(diǎn)的結(jié)合。 它既包含了橫切邏輯的定義, 也包括了連接點(diǎn)的定義. Spring AOP 就是負(fù)責(zé)實(shí)施切面的框架, 它將切面所定義的橫切邏輯編織到切面所指定的連接點(diǎn)中.
AOP 的工作重心在于如何將增強(qiáng)編織目標(biāo)對(duì)象的連接點(diǎn)上, 這里包含兩個(gè)工作:

  • 如何通過 pointcut 和 advice 定位到特定的 joinpoint 上
  • 如何在 advice 中編寫切面代碼.

可以簡單地認(rèn)為, 使用 @Aspect 注解的類就是切面.

在這里插入圖片描述

解釋基于XML Schema方式的切面實(shí)現(xiàn)

在這種情況下召衔,切面由常規(guī)類以及基于XML的配置實(shí)現(xiàn)铃诬。

解釋基于注解的切面實(shí)現(xiàn)

在這種情況下(基于@AspectJ的實(shí)現(xiàn)),涉及到的切面聲明的風(fēng)格與帶有java5標(biāo)注的普通java類一致苍凛。

有幾種不同類型的自動(dòng)代理趣席?

BeanNameAutoProxyCreator

DefaultAdvisorAutoProxyCreator

Metadata autoproxying

面試難免讓人焦慮不安。經(jīng)歷過的人都懂的醇蝴。但是如果你提前預(yù)測面試官要問你的問題并想出得體的回答方式宣肚,就會(huì)容易很多。

上述面試題答案都整理成文檔筆記悠栓。 也還整理了一些面試資料&最新2020收集的一些大廠的面試真題(都整理成文檔霉涨,小部分截圖),有需要的可以點(diǎn)擊進(jìn)入暗號(hào):簡書

image

Java后端進(jìn)階必備筆記

image

mysql高級(jí)調(diào)優(yōu)筆記

image

Spring源碼筆記

image

大廠面試真題

image
image

跳槽解析闸迷,簡歷解析

image
image

總結(jié)

雖然面試套路眾多嵌纲,但對(duì)于技術(shù)面試來說,主要還是考察一個(gè)人的技術(shù)能力和溝通能力腥沽。不同類型的面試官根據(jù)自身的理解問的問題也不盡相同,沒有規(guī)律可循鸠蚪。 有些面試官喜歡問自己擅長的問題今阳,比如在實(shí)際編程中遇到的或者他自己一直在琢磨的這方面的問題,還有些面試官茅信,尤其是大廠的比如 BAT 的面試官喜歡問面試者認(rèn)為自己擅長的盾舌,然后通過提問的方式深挖細(xì)節(jié),刨根到底蘸鲸。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末妖谴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子酌摇,更是在濱河造成了極大的恐慌膝舅,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窑多,死亡現(xiàn)場離奇詭異仍稀,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)埂息,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門技潘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遥巴,“玉大人,你說我怎么就攤上這事享幽〔” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵值桩,是天一觀的道長迹炼。 經(jīng)常有香客問我,道長颠毙,這世上最難降的妖魔是什么斯入? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蛀蜜,結(jié)果婚禮上刻两,老公的妹妹穿的比我還像新娘。我一直安慰自己滴某,他們只是感情好磅摹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著霎奢,像睡著了一般户誓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幕侠,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天帝美,我揣著相機(jī)與錄音,去河邊找鬼晤硕。 笑死悼潭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舞箍。 我是一名探鬼主播舰褪,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疏橄!你這毒婦竟也來了占拍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤捎迫,失蹤者是張志新(化名)和其女友劉穎晃酒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體立砸,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡掖疮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颗祝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浊闪。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恼布,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搁宾,到底是詐尸還是另有隱情折汞,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布盖腿,位于F島的核電站爽待,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏翩腐。R本人自食惡果不足惜鸟款,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茂卦。 院中可真熱鬧何什,春花似錦、人聲如沸等龙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛛砰。三九已至罐栈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泥畅,已是汗流浹背荠诬。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涯捻,地道東北人浅妆。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像障癌,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辩尊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353