一. 介紹一下Spring IOC (控制反轉(zhuǎn)衙熔,依賴注入)?
????????Spring支持三種依賴注入方式澄暮,分別是屬性(Setter方法)注入九孩,構(gòu)造注入和接口注入先馆。
????????在Spring中,那些組成應(yīng)用的主體及由Spring IOC容器所管理的對(duì)象被稱之為Bean躺彬。
????????Spring的IOC容器通過(guò)反射的機(jī)制實(shí)例化Bean并建立Bean之間的依賴關(guān)系煤墙。
????????簡(jiǎn)單地講梅惯,Bean就是由Spring IOC容器初始化、裝配及被管理的對(duì)象仿野。
????????獲取Bean對(duì)象的過(guò)程铣减,首先通過(guò)Resource加載配置文件并啟動(dòng)IOC容器,然后通過(guò)getBean方法獲取bean對(duì)象脚作,就可以調(diào)用他的方法葫哗。
????????IoC的優(yōu)點(diǎn):降低了組件之間的耦合,降低了業(yè)務(wù)對(duì)象之間替換的復(fù)雜性球涛,使之能夠靈活的管理對(duì)象魄梯。
二.? Spring Bean的作用域?
????????Singleton:Spring IOC容器中只有一個(gè)共享的Bean實(shí)例,一般都是Singleton作用域宾符。
????????Prototype:每一個(gè)請(qǐng)求,會(huì)產(chǎn)生一個(gè)新的Bean實(shí)例灭翔。
????????Request:每一次http請(qǐng)求會(huì)產(chǎn)生一個(gè)新的Bean實(shí)例魏烫。
三.?Spring有哪些優(yōu)點(diǎn)?
? ??????輕量級(jí):Spring在大小和透明性方面絕對(duì)屬于輕量級(jí)的肝箱,基礎(chǔ)版本的Spring框架大約只有2MB哄褒。
? ??????控制反轉(zhuǎn)(IOC):Spring使用控制反轉(zhuǎn)技術(shù)實(shí)現(xiàn)了松耦合。依賴被注入到對(duì)象煌张,而不是創(chuàng)建或?qū)ふ乙蕾噷?duì)象呐赡。
? ??????面向切面編程(AOP):?Spring支持面向切面編程,同時(shí)把應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)的服務(wù)分離開(kāi)來(lái)骏融。
? ??????容器:Spring包含并管理應(yīng)用程序?qū)ο蟮呐渲眉吧芷凇?/p>
? ??????MVC框架:Spring的web框架是一個(gè)設(shè)計(jì)優(yōu)良的web MVC框架链嘀,很好的取代了一些web框架。
? ??????事務(wù)管理:Spring對(duì)下至本地業(yè)務(wù)上至全局業(yè)務(wù)(JAT)提供了統(tǒng)一的事務(wù)管理接口档玻。
? ??????異常處理:Spring提供一個(gè)方便的API將特定技術(shù)的異常(由JDBC, Hibernate, 或JDO拋出)轉(zhuǎn)化為一致的怀泊、Unchecked異常。
四. Spring框架有哪些模塊误趴?
? ??????Spring DAO:Spring提供了對(duì)JDBC的操作支持:JdbcTemplate模板工具類 霹琼。
? ??????Spring ORM:Spring可以與ORM框架整合。例如Spring整合Hibernate框架凉当,其中Spring還提供HibernateDaoSupport工具類枣申,簡(jiǎn)化了Hibernate的操作 。
? ??????Spring WEB:Spring提供了對(duì)Struts看杭、Springmvc的支持忠藤,支持WEB開(kāi)發(fā)。與此同時(shí)Spring自身也提供了基于MVC的解決方案 楼雹。
? ??????Spring ?AOP:Spring提供面向切面的編程熄驼,可以給某一層提供事務(wù)管理像寒,例如在Service層添加事物控制 。
? ??????Spring ? JEE:J2EE開(kāi)發(fā)規(guī)范的支持瓜贾,例如EJB 诺祸。
? ??????Spring Core:提供IOC容器對(duì)象的創(chuàng)建和處理依賴對(duì)象關(guān)系 。
五.Spring下IOC容器和DI(依賴注入Dependency injection)?
? ??????IOC容器:就是具有依賴注入功能的容器祭芦,是可以創(chuàng)建對(duì)象的容器筷笨,IOC容器負(fù)責(zé)實(shí)例化、定位龟劲、配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴胃夏。通常new一個(gè)實(shí)例,控制權(quán)由程序員控制昌跌,而"控制反轉(zhuǎn)"是指new實(shí)例工作不由程序員來(lái)做而是交給Spring容器來(lái)做仰禀。。在Spring中BeanFactory是IOC容器的實(shí)際代表者蚕愤。
? ??????DI(依賴注入Dependency injection):在容器創(chuàng)建對(duì)象后答恶,處理對(duì)象的依賴關(guān)系。
六.? 依賴注入spring的注入方式?
? ??????set注入方式
? ??????靜態(tài)工廠注入方式
? ??????構(gòu)造方法注入方式
? ? ? ? 實(shí)例工廠的方式
七 . Spring常用注解有哪些萍诱?
????????@Component? ? ? ? 把對(duì)象加入ioc容器悬嗓,對(duì)象引用名稱是類名,第一個(gè)字母小寫
????????@Component(“name”) 把指定名稱的對(duì)象裕坊,加入ioc容器
????????@Repository? ? ? ? ?主要用于標(biāo)識(shí)加入容器的對(duì)象是一個(gè)持久層的組件(類)
????????@Service? ? ? ? ????? 主要用于標(biāo)識(shí)加入容器的對(duì)象是一個(gè)業(yè)務(wù)邏輯層的組件
????????@Controller? ? ? ? ? 主要用于標(biāo)識(shí)加入容器的對(duì)象是一個(gè)控制層的組件
????????@Resource? ? ? ? ? 注入屬性(DI), 會(huì)從容器中找對(duì)象注入到@Resource修飾的對(duì)象上
????????@Autowired? ? ? ? ? 注入屬性(DI), 會(huì)從容器中找對(duì)象注入到@Autowired修飾的對(duì)象上
八.? Spring AOP應(yīng)用場(chǎng)景?
????????性能檢測(cè)包竹,訪問(wèn)控制,日志管理籍凝,事務(wù)等周瞎。
九. SpringMVC運(yùn)行原理
????????客戶端請(qǐng)求提交到DispatcherServlet
????????由DispatcherServlet控制器查詢HandlerMapping,找到并分發(fā)到指定的Controller中饵蒂。
????????Controller調(diào)用業(yè)務(wù)邏輯處理后堰氓,返回ModelAndView
????????DispatcherServlet查詢一個(gè)或多個(gè)ViewResoler視圖解析器,找到ModelAndView指定的視圖
????????負(fù)責(zé)將結(jié)果顯示到客戶端
10.? Spring事務(wù)配置方法苹享?
????????1.切點(diǎn)信息双絮,用于定位實(shí)施事物切面的業(yè)務(wù)類方法
????????2.控制事務(wù)行為的事務(wù)屬性,這些屬性包括事物隔離級(jí)別得问,事務(wù)傳播行為囤攀,超時(shí)時(shí)間,回滾規(guī)則宫纬。
????????Spring通過(guò)aop/tx Schema 命名空間和@Transaction注解技術(shù)來(lái)進(jìn)行聲明式事物配置焚挠。
11.??IOC和DI由什么關(guān)系呢?
????????其實(shí)它們是同一個(gè)概念的不同角度描述漓骚,由于控制反轉(zhuǎn)概念比較含糊(可能只是理解為容器控制對(duì)象這一個(gè)層面蝌衔,很難讓人想到誰(shuí)來(lái)維護(hù)對(duì)象關(guān)系)榛泛,所以2004年大師級(jí)人物Martin Fowler又給出了一個(gè)新的名字:“依賴注入”,相對(duì)IoC 而言噩斟,“依賴注入”明確描述了“被注入對(duì)象依賴IoC容器配置依賴對(duì)象”曹锨。
12.??IOC的實(shí)現(xiàn)原理是什么?
???????? IOC的重點(diǎn)是在系統(tǒng)運(yùn)行過(guò)程中剃允,動(dòng)態(tài)的向某個(gè)對(duì)象提供它所需要的其它對(duì)象沛简。這個(gè)提供的方法是通過(guò)DI(依賴注入)來(lái)實(shí)現(xiàn)的。比如斥废,A類需要一個(gè)B類對(duì)象來(lái)完成某個(gè)動(dòng)作椒楣,以前是A類自己new一個(gè)B,有了Spring之后牡肉,只需要告訴spring捧灰,A中需要一個(gè)B,至于B怎么構(gòu)造统锤,何時(shí)構(gòu)造毛俏,A完全不需要care,只需要在它需要的時(shí)候張嘴要就行了跪另。在系統(tǒng)運(yùn)行時(shí),spring會(huì)在適當(dāng)時(shí)候制造一個(gè)B煤搜,然后像打針一樣免绿,注射到A中,從而完成了對(duì)象之間的關(guān)聯(lián)控制擦盾。A需要依賴B才可以正常運(yùn)行嘲驾,而B(niǎo)對(duì)象是由spring注入到A中去的。依賴注入就是這么來(lái)的迹卢。
13. DI的實(shí)現(xiàn)辽故?
????????DI是通過(guò)反射來(lái)實(shí)現(xiàn)的,反射允許程序通過(guò)某個(gè)類的名字或者對(duì)象來(lái)得到類本身腐碱。spring就是通過(guò)反射來(lái)完成注入的誊垢。
14.?AOP兩種代理方式?
????????Spring提供了兩種方式來(lái)生成代理對(duì)象: JDKProxy和Cglib症见,具體使用哪種方式生成由AopProxyFactory根據(jù)AdvisedSupport對(duì)象的配置來(lái)決定喂走。默認(rèn)的策略是如果目標(biāo)類是接口,則使用JDK動(dòng)態(tài)代理技術(shù)谋作,否則使用Cglib來(lái)生成代理芋肠。
15.?IOC底層實(shí)現(xiàn)原理?
????????底層實(shí)現(xiàn)使用的技術(shù):
? ? ? ? 1)xml配置文件
? ? ? ? 2)dom4j解析xml
? ? ? ? 3)工廠模式
? ? ? ? 4)反射
? ? ? ?首先遵蚜,通過(guò)dom4j將我們的配置文件讀取帖池,這時(shí)我們就可以解析到所有相關(guān)的類的全路徑了奈惑。然后,它再利用反射機(jī)制通過(guò)如下代碼完成類的實(shí)例化:類1=Class.forName("類1的全路徑")睡汹。這時(shí)肴甸,我們就得到了類1。(這也是為啥當(dāng)我們的類的全路徑寫錯(cuò)了會(huì)導(dǎo)致出現(xiàn)classNotfind的錯(cuò)誤帮孔。)
? ? ? ?當(dāng)我們得到了類1以后雷滋,通過(guò)調(diào)用類1的set方法,將屬性給對(duì)象進(jìn)行注入文兢。而且晤斩,需要遵循首字母大寫的set規(guī)范。例如:我們的類中有個(gè)字段的屬性為name那么set方法必須寫成setName(name 的首字母要大寫)否則會(huì)報(bào)一個(gè)屬性找不到的錯(cuò)誤:
publicvoid setName(String name){
? ????? this.name= name;
}
? ? ? ?對(duì)象創(chuàng)建后姆坚,我們將我們的對(duì)象id和我們的對(duì)象物理地址澳泵,一起存入類似于HashMap的容器中,然后呢兼呵,我們是如何獲得我們需要的對(duì)象兔辅,然后執(zhí)行對(duì)象中的方法呢?我們通過(guò)getBean的方法击喂,通過(guò)對(duì)象Id獲得對(duì)象的物理地址维苔,得到對(duì)象,然后調(diào)用對(duì)象的方法懂昂,完成對(duì)方法的調(diào)用介时。
16. SpringAOP?的具體加載步驟?
????????1)當(dāng)?spring?容器啟動(dòng)的時(shí)候凌彬,加載了?spring?的配置文件沸柔。
????????2)為配置文件中的所有?bean?創(chuàng)建對(duì)象。
????????3)spring?容器會(huì)解析?aop:config?的配置
? ? ? ? 解析切入點(diǎn)表達(dá)式铲敛,用切入點(diǎn)表達(dá)式和納入?spring?容器中的?bean?做匹配褐澎。如果匹配成功,則會(huì)為該?bean?創(chuàng)建代理對(duì)象伐蒋,代理對(duì)象的方法=目標(biāo)方法+通知工三,如果匹配不成功,不會(huì)創(chuàng)建代理對(duì)象先鱼。
? ? ? ? 4)在客戶端利用?context.getBean()?獲取對(duì)象時(shí)徒蟆,如果該對(duì)象有代理對(duì)象,則返回代理對(duì)象型型;如果沒(méi)有段审,則返回目標(biāo)對(duì)象。
說(shuō)明:如果目標(biāo)類沒(méi)有實(shí)現(xiàn)接口,則?spring?容器會(huì)采用?cglib?的方式產(chǎn)生代理對(duì)象寺枉,如果實(shí)現(xiàn)了接口抑淫,則會(huì)采用?jdk?的方式
17. BeanFactroy 與?ApplicationContext 的區(qū)別?
? ? ????BeanFactory是Spring框架最核心的接口,它提供了高級(jí)IOC的配置機(jī)制姥闪。ApplicationContext建立在BeanFactory基礎(chǔ)之上始苇,提供了更多面向應(yīng)用的功能,它提供了國(guó)際化支持和框架事件體系筐喳,更易于創(chuàng)建實(shí)際應(yīng)用催式。一般稱BeanFactory為IOC容器,而稱ApplicationContext為應(yīng)用上下文避归。
????? ? BeanFactory是一個(gè)類工廠荣月,可以創(chuàng)建并管理各種類的對(duì)象,Spring稱這些創(chuàng)建和管理的Java對(duì)象為Bean梳毙。ApplicationContext由BeanFactory派生而來(lái)哺窄,提供了更多面向?qū)嶋H應(yīng)用的功能。在BeanFactory中账锹,很多功能需要以編程的方式方式實(shí)現(xiàn)萌业,而在ApplicationContext中則可以通過(guò)配置的方式實(shí)現(xiàn)。
? ???????BeanFactory負(fù)責(zé)讀取bean配置文檔奸柬,管理bean的加載生年,實(shí)例化,維護(hù)bean之間的依賴關(guān)系廓奕,負(fù)責(zé)bean的聲明周期抱婉。ApplicationContext除了提供上述BeanFactory所能提供的功能之外,還提供了更完整的框架功能:
????????a. MessageSource, 提供國(guó)際化的消息訪問(wèn)
????????b. 資源訪問(wèn)懂从,如URL和文件
????????c. 事件傳播特性授段,即支持aop特性
????????d. 載入多個(gè)(有繼承關(guān)系)上下文 蹲蒲,使得每一個(gè)上下文都專注于一個(gè)特定的層次番甩,比如應(yīng)用的web層
? ? ? ?1)BeanFactroy采用的是延遲加載形式來(lái)注入Bean的,即只有在使用到某個(gè)Bean時(shí)(調(diào)用getBean())届搁,才對(duì)該Bean進(jìn)行加載實(shí)例化缘薛,這樣,我們就不能發(fā)現(xiàn)一些存在的Spring的配置問(wèn)題卡睦。而ApplicationContext則相反宴胧,它是在容器啟動(dòng)時(shí),一次性創(chuàng)建了所有的Bean表锻。這樣恕齐,在容器啟動(dòng)時(shí),我們就可以發(fā)現(xiàn)Spring中存在的配置錯(cuò)誤瞬逊。?相對(duì)于基本的BeanFactory显歧,ApplicationContext 唯一的不足是占用內(nèi)存空間仪或。當(dāng)應(yīng)用程序配置Bean較多時(shí),程序啟動(dòng)較慢士骤。
????????BeanFacotry延遲加載范删,如果Bean的某一個(gè)屬性沒(méi)有注入,BeanFacotry加載后拷肌,直至第一次使用調(diào)用getBean方法才會(huì)拋出異常到旦;而ApplicationContext則在初始化自身是檢驗(yàn),這樣有利于檢查所依賴屬性是否注入巨缘;所以通常情況下我們選擇使用 ApplicationContext添忘。
????????應(yīng)用上下文則會(huì)在上下文啟動(dòng)后預(yù)載入所有的單實(shí)例Bean。通過(guò)預(yù)載入單實(shí)例bean带猴,確保當(dāng)你需要的時(shí)候昔汉,你就不用等待,因?yàn)樗鼈円呀?jīng)創(chuàng)建好了拴清。
? ? ? 2)BeanFactory和ApplicationContext都支持BeanPostProcessor靶病、BeanFactoryPostProcessor的使用,但兩者之間的區(qū)別是:BeanFactory需要手動(dòng)注冊(cè)口予,而ApplicationContext則是自動(dòng)注冊(cè)娄周。(Applicationcontext比 beanFactory 加入了一些更好使用的功能。而且 beanFactory 的許多功能需要通過(guò)編程實(shí)現(xiàn)而 Applicationcontext 可以通過(guò)配置實(shí)現(xiàn)沪停。比如后處理 bean 煤辨, Applicationcontext 直接配置在配置文件即可而 beanFactory 這要在代碼中顯示的寫出來(lái)才可以被容器識(shí)別。?)
? ? ? ?3)beanFactory主要是面對(duì)與 spring 框架的基礎(chǔ)設(shè)施木张,面對(duì) spring 自己众辨。而 Applicationcontex 主要面對(duì)與 spring 使用的開(kāi)發(fā)者∠侠瘢基本都會(huì)使用 Applicationcontex 并非 beanFactory 鹃彻。
18.?AOP的實(shí)現(xiàn)方式有哪幾種?如何選擇妻献?
????????JDK 動(dòng)態(tài)代理實(shí)現(xiàn)和 cglib 實(shí)現(xiàn)蛛株。
選擇:
????????1)如果目標(biāo)對(duì)象實(shí)現(xiàn)了接口,默認(rèn)情況下會(huì)采用 JDK 的動(dòng)態(tài)代理實(shí)現(xiàn) AOP育拨,也可以強(qiáng)制使用 cglib 實(shí)現(xiàn) AOP谨履;
????????2)如果目標(biāo)對(duì)象沒(méi)有實(shí)現(xiàn)接口,必須采用 cglib 庫(kù)熬丧,Spring 會(huì)自動(dòng)在 JDK 動(dòng)態(tài)代理和 cglib 之間轉(zhuǎn)換笋粟。
19.?JDK動(dòng)態(tài)代理如何實(shí)現(xiàn)?
? ? ? ?JDK 動(dòng)態(tài)代理,只能對(duì)實(shí)現(xiàn)了接口的類生成代理害捕,而不是針對(duì)類唆香,該目標(biāo)類型實(shí)現(xiàn)的接口都將被代理。原理是通過(guò)在運(yùn)行期間創(chuàng)建一個(gè)接口的實(shí)現(xiàn)類來(lái)完成對(duì)目標(biāo)對(duì)象的代理吨艇。
????????1)定義一個(gè)實(shí)現(xiàn)接口 InvocationHandler 的類躬它;
????????2)通過(guò)構(gòu)造函數(shù),注入被代理類东涡;
????????3)實(shí)現(xiàn) invoke( Object proxy, Method method, Object[] args)方法冯吓;
????????4)在主函數(shù)中獲得被代理類的類加載器;
????????5)使用 Proxy.newProxyInstance( ) 產(chǎn)生一個(gè)代理對(duì)象疮跑;
????????6)通過(guò)代理對(duì)象調(diào)用各種方法组贺。
20.?依賴注入方式?
? ? ? ?對(duì)于spring配置一個(gè)bean時(shí),如果需要給該bean提供一些初始化參數(shù)祖娘,則需要通過(guò)依賴注入方式失尖,所謂的依賴注入就是通過(guò)spring將bean所需要的一些參數(shù)傳遞到bean實(shí)例對(duì)象的過(guò)程,spring的依賴注入有3種方式:
? ??????1)使用屬性的setter方法注入 渐苏,這是最常用的方式掀潮。屬性注入即通過(guò)setXxx()方法注入Bean的屬性值或依賴對(duì)象,由于屬性注入方式具有可選擇性和靈活性高的優(yōu)點(diǎn)琼富,因此屬性注入是實(shí)際應(yīng)用中最常采用的注入方式仪吧。
? ? ? ? 2)使用構(gòu)造器注入。在類中鞠眉,不用為屬性設(shè)置setter方法薯鼠,但是需要生成該類帶參的構(gòu)造方法。同時(shí)械蹋,在配置文件中配置該類的bean出皇,并配置構(gòu)造器,在配置構(gòu)造器中用到了節(jié)點(diǎn)哗戈,可以指定按類型匹配入?yún)⑦€是按索引匹配入?yún)ⅰ?/b>
? ? ? ? 3)使用Filed注入(用于注解方式)郊艘。使用注解注入依賴對(duì)象不用再在代碼中寫依賴對(duì)象的setter方法或者該類的構(gòu)造方法,并且不用再配置文件中配置大量的依賴對(duì)象谱醇,使代碼更加簡(jiǎn)潔暇仲,清晰步做,易于維護(hù)副渴。在Spring IOC編程的實(shí)際開(kāi)發(fā)中推薦使用注解的方式進(jìn)行依賴注入。