1、什么是Spring?
Spring是一個開源的Java EE開發(fā)框架谷浅。Spring框架的核心功能可以應(yīng)用在任何Java應(yīng)用程序中即彪,但對Java EE平臺上的Web應(yīng)用程序有更好的擴展性。Spring框架的目標(biāo)是使得Java EE應(yīng)用程序的開發(fā)更加簡捷评甜,通過使用POJO為基礎(chǔ)的編程模型促進良好的編程風(fēng)格灰粮。
2、Spring有哪些優(yōu)點忍坷?
輕量級:Spring在大小和透明性方面絕對屬于輕量級的粘舟,基礎(chǔ)版本的Spring框架大約只有2MB熔脂。
控制反轉(zhuǎn)(IOC):Spring使用控制反轉(zhuǎn)技術(shù)實現(xiàn)了松耦合。依賴被注入到對象柑肴,而不是創(chuàng)建或?qū)ふ乙蕾噷ο蟆?/p>
面向切面編程(AOP): Spring支持面向切面編程霞揉,同時把應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)的服務(wù)分離開來。
容器:Spring包含并管理應(yīng)用程序?qū)ο蟮呐渲眉吧芷凇?/p>
MVC框架:Spring的web框架是一個設(shè)計優(yōu)良的web MVC框架晰骑,很好的取代了一些web框架适秩。
事務(wù)管理:Spring對下至本地業(yè)務(wù)上至全局業(yè)務(wù)(JAT)提供了統(tǒng)一的事務(wù)管理接口。
異常處理:Spring提供一個方便的API將特定技術(shù)的異常(由JDBC, Hibernate, 或JDO拋出)轉(zhuǎn)化為一致的硕舆、Unchecked異常秽荞。
3、Spring 事務(wù)實現(xiàn)方式
編程式事務(wù)管理:這意味著你可以通過編程的方式管理事務(wù)岗宣,這種方式帶來了很大的靈活性蚂会,但很難維護。
聲明式事務(wù)管理:這種方式意味著你可以將事務(wù)管理和業(yè)務(wù)代碼分離耗式。你只需要通過注解或者XML配置管理事務(wù)胁住。
4、Spring框架的事務(wù)管理有哪些優(yōu)點
它為不同的事務(wù)API(如JTA, JDBC, Hibernate, JPA, 和JDO)提供了統(tǒng)一的編程模型刊咳。
它為編程式事務(wù)管理提供了一個簡單的API而非一系列復(fù)雜的事務(wù)API(如JTA).
它支持聲明式事務(wù)管理彪见。
它可以和Spring 的多種數(shù)據(jù)訪問技術(shù)很好的融合。
5娱挨、spring事務(wù)定義的傳播規(guī)則
PROPAGATION_REQUIRED: 支持當(dāng)前事務(wù)余指,如果當(dāng)前沒有事務(wù),就新建一個事務(wù)跷坝。這是最常見的選擇酵镜。
PROPAGATION_SUPPORTS: 支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù)柴钻,就以非事務(wù)方式執(zhí)行淮韭。
PROPAGATION_MANDATORY: 支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù)贴届,就拋出異常靠粪。
PROPAGATION_REQUIRES_NEW: 新建事務(wù),如果當(dāng)前存在事務(wù)毫蚓,把當(dā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ù)嗅虏,則進行與PROPAGATION_REQUIRED類似的操作。
6上沐、Spring 事務(wù)底層原理
劃分處理單元——IoC
由于spring解決的問題是對單個數(shù)據(jù)庫進行局部事務(wù)處理的皮服,具體的實現(xiàn)首先用spring中的IoC劃分了事務(wù)處理單元。并且將對事務(wù)的各種配置放到了ioc容器中(設(shè)置事務(wù)管理器参咙,設(shè)置事務(wù)的傳播特性及隔離機制)龄广。
AOP攔截需要進行事務(wù)處理的類
Spring事務(wù)處理模塊是通過AOP功能來實現(xiàn)聲明式事務(wù)處理的,具體操作(比如事務(wù)實行的配置和讀取蕴侧,事務(wù)對象的抽象)择同,用TransactionProxyFactoryBean接口來使用AOP功能,生成proxy代理對象净宵,通過TransactionInterceptor完成對代理方法的攔截敲才,將事務(wù)處理的功能編織到攔截的方法中。讀取ioc容器事務(wù)配置屬性择葡,轉(zhuǎn)化為spring事務(wù)處理需要的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(TransactionAttributeSourceAdvisor)紧武,轉(zhuǎn)化為TransactionAttribute表示的數(shù)據(jù)對象。
對事務(wù)處理實現(xiàn)(事務(wù)的生成敏储、提交阻星、回滾、掛起)
spring委托給具體的事務(wù)處理器實現(xiàn)已添。實現(xiàn)了一個抽象和適配妥箕。適配的具體事務(wù)處理器:DataSource數(shù)據(jù)源支持、hibernate數(shù)據(jù)源事務(wù)處理支持更舞、JDO數(shù)據(jù)源事務(wù)處理支持畦幢,JPA、JTA數(shù)據(jù)源事務(wù)處理支持疏哗。這些支持都是通過設(shè)計PlatformTransactionManager呛讲、AbstractPlatforTransaction一系列事務(wù)處理的支持。 為常用數(shù)據(jù)源支持提供了一系列的TransactionManager返奉。
結(jié)合
PlatformTransactionManager實現(xiàn)了TransactionInterception接口贝搁,讓其與TransactionProxyFactoryBean結(jié)合起來,形成一個Spring聲明式事務(wù)處理的設(shè)計體系芽偏。
7雷逆、Spring MVC 運行流程
第一步:發(fā)起請求到前端控制器(DispatcherServlet)
第二步:前端控制器請求HandlerMapping查找 Handler( 可以根據(jù)xml配置、注解進行查找)
第三步:處理器映射器HandlerMapping向前端控制器返回Handler
第四步:前端控制器調(diào)用處理器適配器去執(zhí)行Handler
第五步:處理器適配器去執(zhí)行Handler
第六步:Handler執(zhí)行完成給適配器返回ModelAndView
第七步:處理器適配器向前端控制器返回ModelAndView(ModelAndView是springmvc框架的一個底層對象污尉,包括Model和view)
第八步:前端控制器請求視圖解析器去進行視圖解析(根據(jù)邏輯視圖名解析成真正的視圖(jsp))
第九步:視圖解析器向前端控制器返回View
第十步:前端控制器進行視圖渲染( 視圖渲染將模型數(shù)據(jù)(在ModelAndView對象中)填充到request域)
第十一步:前端控制器向用戶響應(yīng)結(jié)果
8膀哲、BeanFactory和ApplicationContext有什么區(qū)別往产?
ApplicationContext提供了一種解決文檔信息的方法,一種加載文件資源的方式(如圖片)某宪,他們可以向監(jiān)聽他們的beans發(fā)送消息仿村。另外,容器或者容器中beans的操作兴喂,這些必須以bean工廠的編程方式處理的操作可以在應(yīng)用上下文中以聲明的方式處理蔼囊。應(yīng)用上下文實現(xiàn)了MessageSource,該接口用于獲取本地消息衣迷,實際的實現(xiàn)是可選的畏鼓。
相同點:兩者都是通過xml配置文件加載bean,ApplicationContext和BeanFacotry相比,提供了更多的擴展功能。
不同點:BeanFactory是延遲加載,如果Bean的某一個屬性沒有注入壶谒,BeanFacotry加載后云矫,直至第一次使用調(diào)用getBean方法才會拋出異常;而ApplicationContext則在初始化自身是檢驗汗菜,這樣有利于檢查所依賴屬性是否注入让禀;所以通常情況下我們選擇使用ApplicationContext。
9呵俏、什么是Spring Beans堆缘?
Spring Beans是構(gòu)成Spring應(yīng)用核心的Java對象。這些對象由Spring IOC容器實例化普碎、組裝吼肥、管理。這些對象通過容器中配置的元數(shù)據(jù)創(chuàng)建麻车,例如缀皱,使用XML文件中定義的創(chuàng)建。
在Spring中創(chuàng)建的beans都是單例的beans动猬。在bean標(biāo)簽中有一個屬性為”singleton”,如果設(shè)為true啤斗,該bean是單例的,如果設(shè)為false赁咙,該bean是原型bean钮莲。Singleton屬性默認設(shè)置為true。因此彼水,spring框架中所有的bean都默認為單例bean崔拥。
10、說一下Spring中支持的bean作用域
Spring框架支持如下五種不同的作用域:
singleton:在Spring IOC容器中僅存在一個Bean實例凤覆,Bean以單實例的方式存在链瓦。
prototype:一個bean可以定義多個實例。
request:每次HTTP請求都會創(chuàng)建一個新的Bean。該作用域僅適用于WebApplicationContext環(huán)境慈俯。
session:一個HTTP Session定義一個Bean渤刃。該作用域僅適用于WebApplicationContext環(huán)境。
globalSession:同一個全局HTTP Session定義一個Bean贴膘。該作用域同樣僅適用于WebApplicationContext環(huán)境卖子。
bean默認的scope屬性是"singleton"。
11刑峡、Spring 的單例實現(xiàn)原理
Spring框架對單例的支持是采用單例注冊表的方式進行實現(xiàn)的揪胃,而這個注冊表的緩存是HashMap對象,如果配置文件中的配置信息不要求使用單例氛琢,Spring會采用新建實例的方式返回對象實例。
12随闪、解釋Spring框架中bean的生命周期
ApplicationContext容器中阳似,Bean的生命周期流程如上圖所示,流程大致如下:
1.首先容器啟動后铐伴,會對scope為singleton且非懶加載的bean進行實例化撮奏,
2.按照Bean定義信息配置信息,注入所有的屬性当宴,
3.如果Bean實現(xiàn)了BeanNameAware接口畜吊,會回調(diào)該接口的setBeanName()方法,傳入該Bean的id户矢,此時該Bean就獲得了自己在配置文件中的id玲献,
4.如果Bean實現(xiàn)了BeanFactoryAware接口,會回調(diào)該接口的setBeanFactory()方法,傳入該Bean的BeanFactory梯浪,這樣該Bean就獲得了自己所在的BeanFactory捌年,
5.如果Bean實現(xiàn)了ApplicationContextAware接口,會回調(diào)該接口的setApplicationContext()方法,傳入該Bean的ApplicationContext挂洛,這樣該Bean就獲得了自己所在的ApplicationContext礼预,
6.如果有Bean實現(xiàn)了BeanPostProcessor接口,則會回調(diào)該接口的postProcessBeforeInitialzation()方法虏劲,
7.如果Bean實現(xiàn)了InitializingBean接口托酸,則會回調(diào)該接口的afterPropertiesSet()方法,
8.如果Bean配置了init-method方法柒巫,則會執(zhí)行init-method配置的方法励堡,
9.如果有Bean實現(xiàn)了BeanPostProcessor接口,則會回調(diào)該接口的postProcessAfterInitialization()方法吻育,
10.經(jīng)過流程9之后念秧,就可以正式使用該Bean了,對于scope為singleton的Bean,Spring的ioc容器中會緩存一份該bean的實例,而對于scope為prototype的Bean,每次被調(diào)用都會new一個新的對象布疼,期生命周期就交給調(diào)用方管理了摊趾,不再是Spring容器進行管理了
11.容器關(guān)閉后币狠,如果Bean實現(xiàn)了DisposableBean接口,則會回調(diào)該接口的destroy()方法砾层,
12.如果Bean配置了destroy-method方法漩绵,則會執(zhí)行destroy-method配置的方法,至此肛炮,整個Bean的生命周期結(jié)束
13止吐、Resource 是如何被查找、加載的侨糟?
Resource 接口是 Spring 資源訪問策略的抽象碍扔,它本身并不提供任何資源訪問實現(xiàn),具體的資源訪問由該接口的實現(xiàn)類完成——每個實現(xiàn)類代表一種資源訪問策略秕重。 Spring 為 Resource 接口提供了如下實現(xiàn)類:
UrlResource:訪問網(wǎng)絡(luò)資源的實現(xiàn)類不同。
ClassPathResource:訪問類加載路徑里資源的實現(xiàn)類。
FileSystemResource:訪問文件系統(tǒng)里資源的實現(xiàn)類溶耘。
ServletContextResource:訪問相對于 ServletContext 路徑里的資源的實現(xiàn)類:
InputStreamResource:訪問輸入流資源的實現(xiàn)類二拐。
ByteArrayResource:訪問字節(jié)數(shù)組資源的實現(xiàn)類。 這些 Resource 實現(xiàn)類凳兵,針對不同的的底層資源百新,提供了相應(yīng)的資源訪問邏輯,并提供便捷的包裝庐扫,以利于客戶端程序的資源訪問饭望。
14、解釋自動裝配的各種模式聚蝶?
自動裝配提供五種不同的模式供Spring容器用來自動裝配beans之間的依賴注入:
no:默認的方式是不進行自動裝配杰妓,通過手工設(shè)置ref 屬性來進行裝配bean。
byName:通過參數(shù)名自動裝配碘勉,Spring容器查找beans的屬性巷挥,這些beans在XML配置文件中被設(shè)置為byName。之后容器試圖匹配验靡、裝配和該bean的屬性具有相同名字的bean卒密。
byType:通過參數(shù)的數(shù)據(jù)類型自動自動裝配妄讯,Spring容器查找beans的屬性扰柠,這些beans在XML配置文件中被設(shè)置為byType次坡。之后容器試圖匹配和裝配和該bean的屬性類型一樣的bean。如果有多個bean符合條件辞州,則拋出錯誤怔锌。
constructor:這個同byType類似,不過是應(yīng)用于構(gòu)造函數(shù)的參數(shù)。如果在BeanFactory中不是恰好有一個bean與構(gòu)造函數(shù)參數(shù)相同類型埃元,則拋出一個嚴重的錯誤涝涤。
autodetect:如果有默認的構(gòu)造方法,通過 construct的方式自動裝配岛杀,否則使用 byType的方式自動裝配阔拳。
15、Spring中的依賴注入是什么类嗤?
依賴注入作為控制反轉(zhuǎn)(IOC)的一個層面糊肠,可以有多種解釋方式。在這個概念中遗锣,你不用創(chuàng)建對象而只需要描述如何創(chuàng)建它們货裹。你不必通過代碼直接的將組件和服務(wù)連接在一起,而是通過配置文件說明哪些組件需要什么服務(wù)精偿。之后IOC容器負責(zé)銜接泪酱。
16、有哪些不同類型的IOC(依賴注入)还最?
構(gòu)造器依賴注入:構(gòu)造器依賴注入在容器觸發(fā)構(gòu)造器的時候完成,該構(gòu)造器有一系列的參數(shù)毡惜,每個參數(shù)代表注入的對象拓轻。
Setter方法依賴注入:首先容器會觸發(fā)一個無參構(gòu)造函數(shù)或無參靜態(tài)工廠方法實例化對象,之后容器調(diào)用bean中的setter方法完成Setter方法依賴注入经伙。
17扶叉、你推薦哪種依賴注入?構(gòu)造器依賴注入還是Setter方法依賴注入帕膜?
你可以同時使用兩種方式的依賴注入枣氧,最好的選擇是使用構(gòu)造器參數(shù)實現(xiàn)強制依賴注入,使用setter方法實現(xiàn)可選的依賴關(guān)系垮刹。
18达吞、Spring IOC 如何實現(xiàn)
Spring中的 org.springframework.beans 包和 org.springframework.context包構(gòu)成了Spring框架IoC容器的基礎(chǔ)。
BeanFactory 接口提供了一個先進的配置機制荒典,使得任何類型的對象的配置成為可能酪劫。ApplicationContex接口對BeanFactory(是一個子接口)進行了擴展,在BeanFactory的基礎(chǔ)上添加了其他功能寺董,比如與Spring的AOP更容易集成覆糟,也提供了處理message resource的機制(用于國際化)、事件傳播以及應(yīng)用層的特別配置遮咖,比如針對Web應(yīng)用的WebApplicationContext滩字。
org.springframework.beans.factory.BeanFactory 是Spring IoC容器的具體實現(xiàn),用來包裝和管理前面提到的各種bean。BeanFactory接口是Spring IoC 容器的核心接口麦箍。
19漓藕、Spring IoC容器是什么?
Spring IOC負責(zé)創(chuàng)建對象内列、管理對象(通過依賴注入)撵术、整合對象、配置對象以及管理這些對象的生命周期话瞧。
20嫩与、IoC有什么優(yōu)點?
IOC或依賴注入減少了應(yīng)用程序的代碼量交排。它使得應(yīng)用程序的測試很簡單划滋,因為在單元測試中不再需要單例或JNDI查找機制。簡單的實現(xiàn)以及較少的干擾機制使得松耦合得以實現(xiàn)埃篓。IOC容器支持勤性單例及延遲加載服務(wù)处坪。
21、解釋AOP模塊
AOP模塊用來開發(fā)Spring應(yīng)用程序中具有切面性質(zhì)的部分架专。該模塊的大部分服務(wù)由AOP Aliance提供同窘,這就保證了Spring框架和其他AOP框架之間的互操作性。另外部脚,該模塊將元數(shù)據(jù)編程引入到了Spring想邦。
22、Spring面向切面編程(AOP)
面向切面編程(AOP):允許程序員模塊化橫向業(yè)務(wù)邏輯委刘,或定義核心部分的功能丧没,例如日志管理和事務(wù)管理。
切面(Aspect) :AOP的核心就是切面锡移,它將多個類的通用行為封裝為可重用的模塊呕童。該模塊含有一組API提供 cross-cutting功能。例如,日志模塊稱為日志的AOP切面淆珊。根據(jù)需求的不同夺饲,一個應(yīng)用程序可以有若干切面。在Spring AOP中施符,切面通過帶有@Aspect注解的類實現(xiàn)钞支。
通知(Advice):通知表示在方法執(zhí)行前后需要執(zhí)行的動作。實際上它是Spring AOP框架在程序執(zhí)行過程中觸發(fā)的一些代碼操刀。Spring切面可以執(zhí)行一下五種類型的通知:
before(前置通知):在一個方法之前執(zhí)行的通知烁挟。
after(最終通知):當(dāng)某連接點退出的時候執(zhí)行的通知(不論是正常返回還是異常退出)。
after-returning(后置通知):在某連接點正常完成后執(zhí)行的通知骨坑。
after-throwing(異常通知):在方法拋出異常退出時執(zhí)行的通知撼嗓。
around(環(huán)繞通知):在方法調(diào)用前后觸發(fā)的通知柬采。
切入點(Pointcut):切入點是一個或一組連接點,通知將在這些位置執(zhí)行且警》勰恚可以通過表達式或匹配的方式指明切入點。
引入:引入允許我們在已有的類上添加新的方法或?qū)傩浴?/p>
目標(biāo)對象:被一個或者多個切面所通知的對象斑芜。它通常是一個代理對象肩刃。也被稱做被通知(advised)對象。
代理:代理是將通知應(yīng)用到目標(biāo)對象后創(chuàng)建的對象杏头。從客戶端的角度看盈包,代理對象和目標(biāo)對象是一樣的。有以下幾種代理:
BeanNameAutoProxyCreator:bean名稱自動代理創(chuàng)建器
DefaultAdvisorAutoProxyCreator:默認通知者自動代理創(chuàng)建器
Metadata autoproxying:元數(shù)據(jù)自動代理
織入:將切面和其他應(yīng)用類型或?qū)ο筮B接起來創(chuàng)建一個通知對象的過程醇王∧卦铮織入可以在編譯、加載或運行時完成寓娩。
23叛氨、Spring AOP 實現(xiàn)原理
實現(xiàn)AOP的技術(shù),主要分為兩大類:
一是采用動態(tài)代理技術(shù)棘伴,利用截取消息的方式寞埠,對該消息進行裝飾,以取代原有對象行為的執(zhí)行焊夸;
二是采用靜態(tài)織入的方式畸裳,引入特定的語法創(chuàng)建“方面”,從而使得編譯器可以在編譯期間織入有關(guān)“方面”的代碼淳地。
Spring AOP 的實現(xiàn)原理其實很簡單:AOP 框架負責(zé)動態(tài)地生成 AOP 代理類,這個代理類的方法則由 Advice和回調(diào)目標(biāo)對象的方法所組成, 并將該對象可作為目標(biāo)對象使用帅容。AOP 代理包含了目標(biāo)對象的全部方法颇象,但AOP代理中的方法與目標(biāo)對象的方法存在差異,AOP方法在特定切入點添加了增強處理并徘,并回調(diào)了目標(biāo)對象的方法遣钳。
Spring AOP使用動態(tài)代理技術(shù)在運行期織入增強代碼。使用兩種代理機制:基于JDK的動態(tài)代理(JDK本身只提供接口的代理)和基于CGlib的動態(tài)代理麦乞。
(1) JDK的動態(tài)代理
JDK的動態(tài)代理主要涉及java.lang.reflect包中的兩個類:Proxy和InvocationHandler蕴茴。其中InvocationHandler只是一個接口,可以通過實現(xiàn)該接口定義橫切邏輯姐直,并通過反射機制調(diào)用目標(biāo)類的代碼倦淀,動態(tài)的將橫切邏輯與業(yè)務(wù)邏輯織在一起。而Proxy利用InvocationHandler動態(tài)創(chuàng)建一個符合某一接口的實例声畏,生成目標(biāo)類的代理對象撞叽。
其代理對象必須是某個接口的實現(xiàn), 它是通過在運行期間創(chuàng)建一個接口的實現(xiàn)類來完成對目標(biāo)對象的代理.只能實現(xiàn)接口的類生成代理,而不能針對類
(2)CGLib
CGLib采用底層的字節(jié)碼技術(shù)姻成,為一個類創(chuàng)建子類,并在子類中采用方法攔截的技術(shù)攔截所有父類的調(diào)用方法愿棋,并順勢織入橫切邏輯.它運行期間生成的代理對象是目標(biāo)類的擴展子類.所以無法通知final科展、private的方法,因為它們不能被覆寫.是針對類實現(xiàn)代理,主要是為指定的類生成一個子類,覆蓋其中方法.
在spring中默認情況下使用JDK動態(tài)代理實現(xiàn)AOP,如果proxy-target-class設(shè)置為true或者使用了優(yōu)化策略那么會使用CGLIB來創(chuàng)建動態(tài)代理.Spring AOP在這兩種方式的實現(xiàn)上基本一樣.以JDK代理為例,會使用JdkDynamicAopProxy來創(chuàng)建代理糠雨,在invoke()方法首先需要織入到當(dāng)前類的增強器封裝到攔截器鏈中才睹,然后遞歸的調(diào)用這些攔截器完成功能的織入.最終返回代理對象.