全網(wǎng)最全Spring面試題之高級篇整理總結(二)(共16題,附超詳細解答)

1.談談你對springIOC和DI的理解,它們有什么區(qū)別?
IoCInverseofControl反轉(zhuǎn)控制的概念,就是將原本在程序中手動創(chuàng)建UserService對象的控制權,交由Spring框架管理,簡單說,就是創(chuàng)建UserService對象控制權被反轉(zhuǎn)到了Spring框架
DI:DependencyInjection依賴注入,在Spring框架負責創(chuàng)建Bean對象時,動態(tài)的將依賴對象注入到Bean組件
面試題:IoC和DI的區(qū)別?
IoC控制反轉(zhuǎn),指將對象的創(chuàng)建權,反轉(zhuǎn)到Spring容器,DI依賴注入,指Spring創(chuàng)建對象的過程中,將對象依賴屬性通過配置進行注入

2.BeanFactory接口和ApplicationContext接口有什么區(qū)別?
①ApplicationContext接口繼承BeanFactory接口,Spring核心工廠是BeanFactory,BeanFactory采取延遲加載,第一次getBean時才會初始化Bean,ApplicationContext是會在加載配置文件時初始化Bean。
②ApplicationContext是對BeanFactory擴展,它可以進行國際化處理、事件傳遞和bean自動裝配以及各種不同應用層的Context實現(xiàn)開發(fā)中基本都在使用ApplicationContext,web項目使用WebApplicationContext,很少用到BeanFactory

BeanFactorybeanFactory=new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
IHelloServicehelloService=(IHelloService) beanFactory.getBean("helloService");
helloService.sayHello();

3.spring配置bean實例化有哪些方式?
1)使用類構造器實例化(默認無參數(shù))

<beanid="bean1" class="cn.itcast.spring.b_instance.Bean1">
</bean>

2)使用靜態(tài)工廠方法實例化(簡單工廠模式)

//下面這段配置的含義:調(diào)用Bean2Factory的getBean2方法得到bean2
<beanid="bean2" class="cn.itcast.spring.b_instance.Bean2Factory"factory-method="getBean2"></bean>

3)使用實例工廠方法實例化(工廠方法模式)

//先創(chuàng)建工廠實例bean3Facory,再通過工廠實例創(chuàng)建目標bean實例
<beanid="bean3Factory" class="cn.itcast.spring.b_instance.Bean3Factory"></bean>
<beanid="bean3"factory-bean="bean3Factory"factory-method="getBean3"></bean>

4.簡單的說一下spring的生命周期?
1.1)在配置<bean>元素,通過init-method指定Bean的初始化方法,通過destroy-method指定Bean銷毀方法

<beanid="lifecyclebean"class="cn.itcast.spring.d_lifecycle.lifecyclebean"init-method="setup"destroy-method="teardown">

需要注意的問題:

</beanid="lifecyclebean"class="cn.itcast.spring.d_lifecycle.lifecyclebean"init-method="setup"destroy-method="teardown">

*destroy-method只對scope="singleton"有效

*銷毀方法,必須關閉ApplicationContext對象(手動調(diào)用),才會被調(diào)用
ClassPathXmlApplicationContext applicationContext=new
ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.close();
2)Bean的完整生命周期(十一步驟)【了解內(nèi)容,但是對于spring內(nèi)部操作理解有一定幫助】
①instantiatebean對象實例化
②populateproperties封裝屬性
③如果Bean實現(xiàn)BeanNameAware執(zhí)行setBeanName
④如果Bean實現(xiàn)BeanFactoryAware或者ApplicationContextAware設置工廠setBeanFactory或者上下文對象setApplicationContext
⑤如果存在類實現(xiàn)BeanPostProcessor(后處理Bean),執(zhí)行postProcessBeforeInitialization,BeanPostProcessor接口提供鉤子函數(shù),用來動態(tài)擴展修改Bean。(程序自動調(diào)用后處理Bean)

publicclassMyBeanPostProcessorimplementsBeanPostProcessor{
publicObject postProcessAfterInitialization(Object bean,StringbeanName)
throwsBeansException{
System.out.println("第八步:后處理Bean,after初始化。");
//后處理Bean,在這里加上一個動態(tài)代理,就把這個Bean給修改了。
returnbean;
//返回bean,表示沒有修改,如果使用動態(tài)代理,返回代理對象,那么就修改了。
}
publicObject postProcessBeforeInitialization(Object bean,StringbeanName)
throwsBeansException{
System.out.println("第五步:后處理Bean的:before初始化??!");
//后處理Bean,在這里加上一個動態(tài)代理,就把這個Bean給修改了。
returnbean;
//返回bean本身,表示沒有修改。
}
}

注意:這個前處理Bean和后處理Bean會對所有的Bean進行攔截。
⑥如果Bean實現(xiàn)InitializingBean執(zhí)行afterPropertiesSet
⑦調(diào)用指定初始化方法init
⑧如果存在類實現(xiàn)BeanPostProcessor(處理Bean),執(zhí)行postProcessAfterInitialization
⑨執(zhí)行業(yè)務處理
⑩如果Bean實現(xiàn)DisposableBean執(zhí)行destroy
?調(diào)用指定銷毀方法customerDestroy

5.請介紹一下Spring框架中Bean的生命周期和作用域
(1)bean定義
1.在配置文件里面用<bean></bean>來進行定義。
(2)bean初始化
1.有兩種方式初始化:
A.在配置文件中通過指定init-method屬性來完成
B.實現(xiàn)org.springframwork.beans.factory.InitializingBean接口
(3)bean調(diào)用
1.有三種方式可以得到bean實例,并進行調(diào)用
(4)bean銷毀
1.銷毀有兩種方式
A.使用配置文件指定的destroy-method屬性
B.實現(xiàn)org.springframwork.bean.factory.DisposeableBean接口

作用域

singleton
當一個bean的作用域為singleton,那么SpringIoC容器中只會存在一個共享的bean實例,并且所有對bean的請求,只要id與該bean定義相匹配,則只會返回bean的同一實例。
prototype
Prototype作用域的bean會導致在每次對該bean請求(將其注入到另一個bean中,或者以程序的方式調(diào)用容器的getBean()方法)時都會創(chuàng)建一個新的bean實例。根據(jù)經(jīng)驗,對所有有狀態(tài)的bean應該使用prototype作用域,而對無狀態(tài)的bean則應該使用singleton作用域request
在一次HTTP請求中,一個bean定義對應一個實例;即每次HTTP請求將會有各自的bean實例,它們依據(jù)某個bean定義創(chuàng)建而成。該作用域僅在基于web的SpringApplicationContext情形下有效。
session
在一個HTTPSession中,一個bean定義對應一個實例。該作用域僅在基于web的SpringApplicationContext情形下有效。
globalsession
在一個全局的HTTPSession中,一個bean定義對應一個實例。典型情況下,僅在使用portletcontext的時候有效。該作用域僅在基于web的SpringApplicationContext情形下有效。

6.Bean注入屬性有哪幾種方式?
spring支持構造器注入和setter方法注入構造器注入,通過元素完成注入setter方法注入,通過元素完成注入【開發(fā)中常用方式】

7.什么是AOP,AOP的作用是什么?
面向切面編程(AOP)提供另外一種角度來思考程序結構,通過這種方式彌補了面向?qū)ο缶幊蹋∣OP)的不足,除了類(classes)以外,AOP提供了切面。切面對關注點進行模塊化,例如橫切多個類型和對象的事務管理Spring的一個關鍵的組件就是AOP框架,可以自由選擇是否使用AOP提供聲明式企業(yè)服務,特別是為了替代EJB聲明式服務。最重要的服務是聲明性事務管理,這個服務建立在Spring的抽象事物管理之上。允許用戶實現(xiàn)自定義切面,用AOP來完善OOP的使用,可以把SpringAOP看作是對Spring的一種增強

8.Spring的核心類有哪些,各有什么作用?
?BeanFactory:產(chǎn)生一個新的實例,可以實現(xiàn)單例模式
?BeanWrapper:提供統(tǒng)一的get及set方法
?ApplicationContext:提供框架的實現(xiàn),包括BeanFactory的所有功能

9.Spring里面如何配置數(shù)據(jù)庫驅(qū)動?
使用”org.springframework.jdbc.datasource.DriverManagerDataSource”數(shù)據(jù)源來配置數(shù)據(jù)庫驅(qū)動。示例如下:

org.hsqldb.jdbcDriverjdbc:hsqldb:db/appfuseabcabc

10.Spring里面applicationContext.xml文件能不能改成其他文件名?
ContextLoaderListener是一個ServletContextListener,它在你的web應用啟動的時候初始化。缺省情況下,它會在WEB-INF/applicationContext.xml文件找Spring的配置。你可以通過定義一個元素名字為”contextConfigLocation”來改變Spring配置文件的位置。示例如下:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/xyz.xml</param-value>
</context-param>
</listener-class>
</listener>

11.Spring里面如何定義hibernatemapping?
添加hibernatemapping文件到web/WEB-INF目錄下的applicationContext.xml文件里面。示例如下:

<propertyname=”mappingResources”>
<list>

<value>org/appfuse/model/User.hbm.xml</value>
</list>
</property>

12.Spring如何處理線程并發(fā)問題?
?Spring使用ThreadLocal解決線程安全問題
?我們知道在一般情況下,只有無狀態(tài)的Bean才可以在多線程環(huán)境下共享,在Spring中,絕大部分Bean都可以聲明為singleton作用域。就是因為Spring對一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非線程安全狀態(tài)采用ThreadLocal進行處理,讓它們也成為線程安全的狀態(tài),因為有狀態(tài)的Bean就可以在多線程中共享了。
?ThreadLocal和線程同步機制都是為了解決多線程中相同變量的訪問沖突問題。
?在同步機制中,通過對象的鎖機制保證同一時間只有一個線程訪問變量。這時該變量是多個線程共享的,使用同步機制要求程序慎密地分析什么時候?qū)ψ兞窟M行讀寫,什么時候需要鎖定某個對象,什么時候釋放對象鎖等繁雜的問題,程序設計和編寫難度相對較大。
?而ThreadLocal則從另一個角度來解決多線程的并發(fā)訪問。ThreadLocal會為每一個線程提供一個獨立的變量副本,從而隔離了多個線程對數(shù)據(jù)的訪問沖突。因為每一個線程都擁有自己的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的變量封裝進ThreadLocal。
?由于ThreadLocal中可以持有任何類型的對象,低版本JDK所提供的get()返回的是Object對象,需要強制類型轉(zhuǎn)換。但JDK5.0通過泛型很好的解決了這個問題,在一定程度地簡化ThreadLocal的使用。
?概括起來說,對于多線程資源共享的問題,同步機制采用了“以時間換空間”的方式,而ThreadLocal采用了“以空間換時間”的方式。前者僅提供一份變量,讓不同的線程排隊訪問,而后者為每一個線程都提供了一份變量,因此可以同時訪問而互不影響。

13.為什么要有事物傳播行為?

14.介紹一下Spring的事物管理
事務就是對一系列的數(shù)據(jù)庫操作(比如插入多條數(shù)據(jù))進行統(tǒng)一的提交或回滾操作,如果插入成功,那么一起成功,如果中間有一條出現(xiàn)異常,那么回滾之前的所有操作。這樣可以防止出現(xiàn)臟數(shù)據(jù),防止數(shù)據(jù)庫數(shù)據(jù)出現(xiàn)問題。
開發(fā)中為了避免這種情況一般都會進行事務管理。Spring中也有自己的事務管理機制,一般是使用TransactionMananger進行管理,可以通過Spring的注入來完成此功能。spring提供了幾個關于事務處理的類:
?TransactionDefinition//事務屬性定義
?TranscationStatus//代表了當前的事務,可以提交,回滾。
?PlatformTransactionManager這個是spring提供的用于管理事務的基礎接口,其下有一個實現(xiàn)的抽象類AbstractPlatformTransactionManager,我們使用的事務管理類例如DataSourceTransactionManager等都是這個類的子類。
一般事務定義步驟:

TransactionDefinitiontd=new TransactionDefinition();
TransactionStatusts=transaction Manager.getTransaction(td);
try{
//dosth
transactionManager.commit(ts);
}catch(Exceptione){
transactionManager.rollback(ts);
}

spring提供的事務管理可以分為兩類:編程式的和聲明式的。編程式的,比較靈活,但是代碼量大,存在重復的代碼比較多;聲明式的比編程式的更靈活。
編程式主要使用transactionTemplate。省略了部分的提交,回滾,一系列的事務對象定義,需注入事務管理對象.

voidadd(){

transactionTemplate.execute(newTransaction Callback(){
pulicObject
doInTransaction(TransactionStatusts){
//dosth
}
}
}

聲明式:
使用
TransactionProxyFactoryBean:PROPAGATIONREQUIREDPROPAGATIONREQUIRED PROPAGATION_REQUIRED,readOnly圍繞Poxy的動態(tài)代理能夠自動的提交和回滾事務

org.springframework.transaction.interceptor.TransactionProxyFactoryBean

PROPAGATION_REQUIRED–支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

PROPAGATION_SUPPORTS–支持當前事務,如果當前沒有事務,就以非事務方式執(zhí)行。

PROPAGATION_MANDATORY–支持當前事務,如果當前沒有事務,就拋出異常。

PROPAGATION_REQUIRES_NEW–新建事務,如果當前存在事務,把當前事務掛起。

PROPAGATION_NOT_SUPPORTED–以非事務方式執(zhí)行操作,如果當前存在事務,就把當前事務掛起。

PROPAGATION_NEVER–以非事務方式執(zhí)行,如果當前存在事務,則拋出異常。

PROPAGATION_NESTED–如果當前存在事務,則在嵌套事務內(nèi)執(zhí)行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。

15.解釋一下SpringAOP里面的幾個名詞
切面(Aspect):一個關注點的模塊化,這個關注點可能會橫切多個對象。事務管理是J2EE應用中一個關于橫切關注點的很好的例子。在
SpringAOP中,切面可以使用通用類(基于模式的風格)或者在普通類中以@Aspect注解(@AspectJ風格)來實現(xiàn)。
連接點(Joinpoint):在程序執(zhí)行過程中某個特定的點,比如某方法調(diào)用的時候或者處理異常的時候。在SpringAOP中,一個連接點總是代表一個方法的執(zhí)行。通過聲明一個org.aspectj.lang.JoinPoint類型的參數(shù)可以使通知(Advice)的主體部分獲得連接點信息。
通知(Advice):在切面的某個特定的連接點(Joinpoint)上執(zhí)行的動作。通知有各種類型,其中包括“around”、“before”和“after”等通知。通知的類型將在后面部分進行討論。許多AOP框架,包括Spring,都是以攔截器做通知模型,并維護一個以連接點為中心的攔截器鏈。
切入點(Pointcut):匹配連接點(Joinpoint)的斷言。通知和一個切入點表達式關聯(lián),并在滿足這個切入點的連接點上運行(例如,當執(zhí)行某個特定名稱的方法時)。
切入點表達式如何和連接點匹配是AOP的核心:Spring缺省使用AspectJ切入點語法。
引入(Introduction):(也被稱為內(nèi)部類型聲明(inter-typedeclaration))。聲明額外的方法或者某個類型的字段。Spring允許引入新的接口(以及一個對應的實現(xiàn))到任何被代理的對象。例如,你可以使用一個引入來使bean實現(xiàn)IsModified接口,以便簡化緩存機制。
目標對象(TargetObject):被一個或者多個切面(aspect)所通知(advise)的對象。也有人把它叫做被通知(advised)對象。既然SpringAOP是通過運行時代理實現(xiàn)的,這個對象永遠是一個被代理(proxied)對象。
AOP代理(AOPProxy):AOP框架創(chuàng)建的對象,用來實現(xiàn)切面契約(aspectcontract)(包括通知方法執(zhí)行等功能)。在Spring中,AOP代理可以是JDK動態(tài)代理或者CGLIB代理。注意:Spring2.0最新引入的基于模式(schema-based)風格和@AspectJ注解風格的切面聲明,對于使用這些風格的用戶來說,代理的創(chuàng)建是透明的。
織入(Weaving):把切面(aspect)連接到其它的應用程序類型或者對象上,并創(chuàng)建一個被通知(advised)的對象。這些可以在編譯時(例如使用AspectJ編譯器),類加載時和運行時完成。Spring和其他純JavaAOP框架一樣,在運行時完成織入。

16.通知有哪些類型?
前置通知(Beforeadvice):在某連接點(joinpoint)之前執(zhí)行的通知,但這個通知不能阻止連接點前的執(zhí)行(除非它拋出一個異常)。
返回后通知(Afterreturningadvice):在某連接點(joinpoint)正常完成后執(zhí)行的通知:例如,一個方法沒有拋出任何異常,正常返回。
拋出異常后通知(Afterthrowingadvice):在方法拋出異常退出時執(zhí)行的通知。
后通知(After(finally)advice):當某連接點退出的時候執(zhí)行的通知(不論是正常返回還是異常退出)。
環(huán)繞通知(AroundAdvice):包圍一個連接點(joinpoint)的通知,如方法調(diào)用。這是最強大的一種通知類型。環(huán)繞通知可以在方法調(diào)用前后完成自定義的行為。它也會選擇是否繼續(xù)執(zhí)行連接點或直接返回它們自己的返回值或拋出異常來結束執(zhí)行。環(huán)繞通知是最常用的一種通知類型。大部分基于攔截的AOP框架,例如Nanning和JBoss4,都只提供環(huán)繞通知。切入點(pointcut)和連接點(joinpoint)匹配的概念是AOP的關鍵,這使得AOP不同于其它僅僅提供攔截功能的舊技術。切入點使得定位通知(advice)可獨立于OO層次。例如,一個提供聲明式事務管理的around通知可以被應用到一組橫跨多個對象中的方法上(例如服務層的所有業(yè)務操作)。

嗨,你好呀,未來的架構師,本文由Java架構師面試網(wǎng)www.javajiagoushi.com收集整理并進行編輯發(fā)布,謝謝大家的支持~

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容