什么是spring?
Spring 是個(gè)java企業(yè)級應(yīng)用的開源開發(fā)框架。Spring主要用來開發(fā)Java應(yīng)用,但是有些擴(kuò)展是針對構(gòu)建J2EE平臺的web應(yīng)用。Spring框架目標(biāo)是簡化Java企業(yè)級應(yīng)用開發(fā),并通過POJO為基礎(chǔ)的編程模型促進(jìn)良好的編程習(xí)慣
使用Spring框架的好處是什么?
輕量:Spring 是輕量的,基本的版本大約2MB。
控制反轉(zhuǎn):Spring通過控制反轉(zhuǎn)實(shí)現(xiàn)了松散耦合,對象們給出它們的依賴,而不是創(chuàng)建或查找依賴的對象們。
面向切面的編程(AOP):Spring支持面向切面的編程,并且把應(yīng)用業(yè)務(wù)邏輯和系統(tǒng)服務(wù)分開。
容器:Spring 包含并管理應(yīng)用中對象的生命周期和配置。
MVC框架:Spring的WEB框架是個(gè)精心設(shè)計(jì)的框架,是Web框架的一個(gè)很好的替代品。
事務(wù)管理:Spring 提供一個(gè)持續(xù)的事務(wù)管理接口,可以擴(kuò)展到上至本地事務(wù)下至全局事務(wù)(JTA)。
異常處理:Spring 提供方便的API把具體技術(shù)相關(guān)的異常(比如由JDBC,Hibernate or JDO拋出的)轉(zhuǎn)化為一致的unchecked 異常。
Spring由哪些模塊組成?
簡單可以分成6大模塊:
Core????AOP????ORM????DAO????Web????Spring EE
什么是Spring的依賴注入?
依賴注入,是IOC的一個(gè)方面,是個(gè)通常的概念,它有多種解釋。這概念是說你不用創(chuàng)建對象,而只需要描述它如何被創(chuàng)建。你不在代碼里直接組裝你的組件和服務(wù),但是要在配置文件里描述哪些組件需要哪些服務(wù),之后一個(gè)容器(IOC容器)負(fù)責(zé)把他們組裝起來。
有哪些不同類型的IOC(依賴注入)方式?
構(gòu)造器依賴注入:構(gòu)造器依賴注入通過容器觸發(fā)一個(gè)類的構(gòu)造器來實(shí)現(xiàn)的,該類有一系列參數(shù),每個(gè)參數(shù)代表一個(gè)對其他類的依賴。
Setter方法注入:Setter方法注入是容器通過調(diào)用無參構(gòu)造器或無參static工廠 方法實(shí)例化bean之后,調(diào)用該bean的setter方法,即實(shí)現(xiàn)了基于setter的依賴注入。
工廠注入:這個(gè)是遺留下來的,很少用的了!
哪種依賴注入方式你建議使用,構(gòu)造器注入,還是 Setter方法注入?
講道理,你兩種依賴方式都可以使用,構(gòu)造器注入和Setter方法注入。最好的解決方案是用構(gòu)造器參數(shù)實(shí)現(xiàn)強(qiáng)制依賴,setter方法實(shí)現(xiàn)可選依賴。
什么是Spring beans?
Spring beans 是那些形成Spring應(yīng)用的主干的java對象。它們被Spring IOC容器初始化,裝配,和管理。這些beans通過容器中配置的元數(shù)據(jù)創(chuàng)建。比如,以XML文件中<bean/>的形式定義。
這里有四種重要的方法給Spring容器提供配置元數(shù)據(jù)。
XML配置文件。
基于注解的配置。
基于java的配置。
Groovy DSL配置
解釋Spring框架中bean的生命周期
Spring容器 從XML 文件中讀取bean的定義,并實(shí)例化bean。
Spring根據(jù)bean的定義填充所有的屬性。
如果bean實(shí)現(xiàn)了BeanNameAware 接口,Spring 傳遞bean 的ID 到 setBeanName方法。
如果Bean 實(shí)現(xiàn)了 BeanFactoryAware 接口, Spring傳遞beanfactory 給setBeanFactory 方法。
如果有任何與bean相關(guān)聯(lián)的BeanPostProcessors,Spring會在postProcesserBeforeInitialization()方法內(nèi)調(diào)用它們。
如果bean實(shí)現(xiàn)IntializingBean了,調(diào)用它的afterPropertySet方法,如果bean聲明了初始化方法,調(diào)用此初始化方法。
如果有BeanPostProcessors 和bean 關(guān)聯(lián),這些bean的postProcessAfterInitialization() 方法將被調(diào)用。
如果bean實(shí)現(xiàn)了 DisposableBean,它將調(diào)用destroy()方法。
解釋不同方式的自動(dòng)裝配
no:默認(rèn)的方式是不進(jìn)行自動(dòng)裝配,通過顯式設(shè)置ref 屬性來進(jìn)行裝配。
byName:通過參數(shù)名 自動(dòng)裝配,Spring容器在配置文件中發(fā)現(xiàn)bean的autowire屬性被設(shè)置成byname,之后容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。
byType::通過參數(shù)類型自動(dòng)裝配,Spring容器在配置文件中發(fā)現(xiàn)bean的autowire屬性被設(shè)置成byType,之后容器試圖匹配、裝配和該bean的屬性具有相同類型的bean。如果有多個(gè)bean符合條件,則拋出錯(cuò)誤。
constructor:這個(gè)方式類似于byType, 但是要提供給構(gòu)造器參數(shù),如果沒有確定的帶參數(shù)的構(gòu)造器參數(shù)類型,將會拋出異常。
autodetect:首先嘗試使用constructor來自動(dòng)裝配,如果無法工作,則使用byType方式。
只用注解的方式時(shí),注解默認(rèn)是使用byType的!
IOC的優(yōu)點(diǎn)是什么?
IOC 或 依賴注入把應(yīng)用的代碼量降到最低。它使應(yīng)用容易測試,單元測試不再需要單例和JNDI查找機(jī)制。最小的代價(jià)和最小的侵入性使松散耦合得以實(shí)現(xiàn)。
IOC容器支持加載服務(wù)時(shí)的餓漢式初始化和懶加載。
簡要談?wù)凙OP
說到AOP?首先想到的是什么??正交性?因?yàn)檎恍缘牧硪粋€(gè)有趣的變體就是面向切面編程?
舉個(gè)例子,如果多個(gè)事務(wù)中一個(gè)發(fā)生變化不會影響其他事務(wù),這些事務(wù)就是正交的?在設(shè)計(jì)良好的系統(tǒng)中,數(shù)據(jù)庫代碼與用戶界面是正交的;
你可以改動(dòng)界面,而不影響數(shù)據(jù)庫,更改數(shù)據(jù)庫,而不用改動(dòng)界面?AOP讓你在一個(gè)地方表達(dá)本來會分散在你源碼各處的某種行為
例如日志消息是在源碼各處,通常顯式地調(diào)用某個(gè)日志函數(shù)生成的,通過AOP,你把日志功能正交地實(shí)現(xiàn)到要進(jìn)行的日志記錄的代碼中
使用AOP的JAVA版本,你可以通過編寫aspect,在進(jìn)入類Fred的任何方法時(shí)寫日志消息?如果你把這個(gè)寫進(jìn)你的代碼,就會生成追蹤消息,否則,你就不會看到任何消息,不管怎樣,你原來的源碼都沒有變化
AOP實(shí)現(xiàn)原理
Spring AOP 中的動(dòng)態(tài)代理主要有兩種方式,JDK 動(dòng)態(tài)代理和CGLIB 動(dòng)態(tài)代理。JDK 動(dòng)態(tài)代理通過反射來接收被代理的類,并且要求被代理的類必須實(shí)現(xiàn)一個(gè)接口。JDK 動(dòng)態(tài)代理的核心是InvocationHandler接口和Proxy類。
如果目標(biāo)類沒有實(shí)現(xiàn)接口,那么 Spring AOP 會選擇使用 CGLIB 來動(dòng)態(tài)代理目標(biāo)類。CGLIB(Code Generation Library),是一個(gè)代碼生成的類庫,可以在運(yùn)行時(shí)動(dòng)態(tài)的生成某個(gè)類的子類,注意,CGLIB 是通過繼承的方式做的動(dòng)態(tài)代理,因此如果某個(gè)類被標(biāo)記為 final,那么它是無法使用 CGLIB 做動(dòng)態(tài)代理的。
怎么回答面試官:你對Spring的理解
Spring最初誕生時(shí)候就是,控制反轉(zhuǎn)和非侵入式。再講講Springboot? 主要是在沒有Springboot的時(shí)候 大家是怎么寫代碼的呢,Spring是為了解決什么問題?
Sring框架用到了那些設(shè)計(jì)原則
代理模式:在 AOP 和 Remoting 中被用的比較多。
單例模式:在 Spring 配置文件中定義的 Bean 默認(rèn)為單例模式。
Spring 的單例實(shí)現(xiàn)原理
比如Spring 對 Bean 實(shí)例的創(chuàng)建是采用單例注冊表的方式進(jìn)行實(shí)現(xiàn)的,而這個(gè)注冊表的緩存是 ConcurrentHashMap 對象。
模板方法:用來解決代碼重復(fù)的問題。比如. RestTemplate, JmsTemplate, JpaTemplate。
前端控制器:Spring 提供了 DispatcherServlet 來對請求進(jìn)行分發(fā)。
視圖幫助(View Helper ):Spring 提供了一系列的 JSP 標(biāo)簽,高效宏來輔助將分散的代碼整合在視圖里。
依賴注入:貫穿于 BeanFactory / ApplicationContext 接口的核心理念。
工廠模式:BeanFactory 用來創(chuàng)建對象的實(shí)例。