-
什么是spring?談談你對IOC和AOP的理解。
Spring:是一個企業級java應用框架,他的作用主要是簡化軟件的開發以及配置過程,簡化項目部署環境。
Spring的優點:
1、Spring低侵入設計,對業務代碼的污染非常低。
2、Spring的DI機制將對象之間的關系交由框架處理,減少組件的耦合。
3、Spring提供了AOP技術,支持將一些通用的功能進行集中式管理,從而提供更好的復用。
4、Spring對于主流框架提供了非常好的支持。
IOC就是控制反轉,指創建對象的控制權轉移給Spring來進行管理。簡單來說,就是應用不用去new對象了,而全部交由 Spring自動生產。
IOC有三種注入方式:1、構造器注入2、setter方法注入3、根據注解注入。
AOP 面向切面。用于將那些與業務無關,但卻對多個對象產生影響的公共行為。抽取并封裝成一個可重用的模塊。AOP的核心就是動態代理。JDK的動態代理和 CGLIB動態代理。
-
什么是bean的自動裝配,有哪些方式?
開啟自動裝配,只需要在xml配置文件<bean>中定義“autowire"屬性。
<bean id="cutomer"c1ass="com.xxx.xxx.Customer" autowire=""/>
autowire屬性有五種裝配的方式:
·no-缺省情況下,自動配置是通過“ref”屬性手動設定
手動裝配:以value或ref的方式明確指定屬性值都是手動裝配。
需要通過‘ref'屬性來連接bean。
·byName-根據bean的屬性名稱進行自動裝配。
Cutomer的屬性名稱是person,Spring會將bean id為person的bean通過setter方法進行自動裝配。
<bean id="cutomer"c1ass="com.xxx.xxx.Cutomer" autowire="byName"/>
<bean id="person" c1ass="com.xxx.xxx.Person"/>
·byType-根據bean的類型進行自動裝配。
Cutomer的屬性person的類型為Person,Spirng會將Person類型通過setter方法進行自動裝配。
<bean id="cutomer" class="com.xxx.xxx.Cutomer" autowire="byType"/>
<bean id="person" class="com.xxx.xxx.Person"/>
.constructor-類似byType,不過是應用于構造器的參數。如果一個bean與構造器參數的類型形同,則進行自動裝配,否則導致異常。
Cutomer構造函數的參數person的類型為Person,Spirng會將Person類型通過構造方法進行自動裝配。
<bean id="cutomer"class="com.xxx.xxx.Cutomer"autowire="construtor"/>
<bean id="person" c1ass="com.xxx.xxx.Persc
autodetect-如果有默認的構造器,則通過constructor方式進行自動裝配,否則使用byType方式進行自動裝配。
如果有默認的構造器,則通過constructor方式進行自動裝配,否則使用byType方式進行自動裝配。
@Autowired自動裝配bean,可以在字段、setter方法、構造函數上使用。
-
如何理解Spring Boot中的Starter
使用spring+springmvc使用,如果需要引入mybatis等框架,需要到xml中定義mybatis需要的bean
starter就是定義一個starter的jar包,寫一個@Configuration配置類、將這些bean定義在里面,然后在starte包的META-INFspring.factories中寫入該配置類,springboot會按照約定來加載該配置類
開發人員只需要將相應的starter包依賴進應用,進行相應的屬性配置(使用默認配置時,不需要配置),就可以直接進行代碼開發,使用對應的功能了,比如mybatis-spring-boot--starter, spring-boot-starter-redis
-
如何實現一個IOC容器
1、配置文件配置包掃描路徑
2、遞歸包掃描獲取.class文件
3、反射、確定需要交給IOC管理的類
4、對需要注入的類進行依賴注入
- ·配置文件中指定需要掃描的包路徑
- ·定義一些注解,分別表示訪問控制層、業務服務層、數據持久層、依賴注入注解、獲取配置文件注解
- ·從配置文件中獲取需要掃描的包路徑,獲取到當前路徑下的文件信息及文件夾信息,我們將當前路徑下所有以.class結尾的文件添加到一個Set集合中進行存儲
- ·遍歷這個set集合,獲取在類上有指定注解的類,并將其交給IOC容器,定義一個安全的Map用來存儲這些對象
- ·遍歷這個IOC容器,獲取到每一個類的實例,判斷里面是有有依賴其他的類的實例,然后進行遞歸注入
-
京東一面:Spring中bean是線程安全的嗎?
Spring本身并沒有針對bean做線程安全的處理,所以:
- 如果bean是無狀態的,那么bean是線程安全的。
- 如果bean是有狀態的,則bean不是線程安全的。
另外,bean是不是線程安全,跟bean的作用域沒有關系,bean的作用域只是表示bean的生命周期的范圍,對于任何生命周期的bean都是一個對象,這個對象是不是線程安全的,還是得看這個bean對象本身。
-
談談你對IOC的理解
容器概念、控制反轉、依賴注入
ioc容器:實際上就是個map (key,value),里面存的是各種對象(在xml里配置的bean節點、@repository、@service、@controller、@component),在項目啟動的時候會讀取配置文件里面的bean節點,根據全限定類名使用反射創建對象放到map里、掃描到打上上述注解的類還是通過反射創建對象放到map里。
這個時候map里就有各種對象了,接下來我們在代碼里需要用到里面的對象時,再通過DI注入(autowired、resource等注解,xml里bean節點內的ref屬性,項目啟動的時候會讀取xml節點ref屬性根據id注入,也會掃描這些注解,根據類型或id注入;id就是對象名)。
控制反轉:
沒有引入IOC容器之前,對象A依賴于對象B,那么對象A在初始化或者運行到某一點的時候,自己必須主動去創建對象B或者使用已經創建的對象B。無論是創建還是使用對象B,控制權都在自己手上。
引入IOC容器之后,對象A與對象B之間失去了直接聯系,當對象A運行到需要對象B的時候,IOC容器會主動創建一個對象B注入到對象A需要的地方。
通過前后的對比,不難看出來:對象A獲得依賴對象B的過程,由主動行為變為了被動行為,控制權顛倒過來了,這就是“控制反轉”這個名稱的由來。
全部對象的控制權全部上交給"第三方”IOC容器,所以,IOC容器成了整個系統的關鍵核心,它起到了一種類似”粘合劑”的作用,把系統中的所有對象粘合在一起發揮作用,如果沒有這個“粘合劑”,對象與對象之間會彼此失去聯系,這就是有人把IOC容器比喻成"粘合劑”的由來。
依賴注入:
“獲得依賴對象的過程被反轉了”。控制被反轉之后,獲得依賴對象的過程由自身管理變為了由IOC容器主動注入。依賴注入是實現IOC的方法,就是由IOC容易在運行期間,動態地將某種依賴關系注入到對象之中。
-
阿里一面:介紹一下Spring,讀過源碼介紹一下大致流程
1.Spring是一個快速開發框架,Spring幫助程序員來管理對象
2.Spring的源碼實現的是非常優秀的,設計模式的應用、并發安全的實現、面向接口的設計等
3.在創建Spring容器,也就是啟動Spring時:
a.首先會進行掃描,掃描得到所有的BeanDefinition對象,并存在一個Map中
b.然后篩選出非懶加載的單例BeanDefinition進行創建Bean,對于多例Bean不需要在啟動過程中去進行創建,對于多例Bean會在每次獲取Bean時利用BeanDefinition去創建
c.利用BeanDefinition創建Bean就是Bean的創建生命周期,這期間包括了合并BeanDefinition、推斷構造方法、實例化、屬性填充、初始化前、初始化、初始化后等步驟,其中AOP就是發生在初始化后這一步驟中
4.單例Bean創建完了之后,Spring會發布一個容器啟動事件
5.Spring啟動結束
6.在源碼中會更復雜,比如源碼中會提供一些模板方法,讓子類來實現,比如源碼中還涉及到一些BeanFactoryPostProcessor和BeanPostProcessor的注冊,Spring的掃描就是通過BenaFactoryPostProcessor來實現的,依賴注入就是通過BeanPostProcessor來實現的
7.在Spring啟動過程中還會去處理@lmport等注解
-
描述一下Srping Bean的生命周期
- 解析類得到BeanDefinition
- 如果有多個構造方法,則要推斷構造方法
- 確定好構造方法后,進行實例化得到一個對象
- 對對象中的加了@Autowired注解的屬性進行屬性賦值
- 回調Aware方法,比如BeanNameAware、BeanFactoryAware
- 調用BeanPostProcessor的初始化前的方法
- 調用初始化方法
- 調用BeanPostProcesspr的初始化后的方法,在這里進行AOP
- 如果當前創建的bean是單例的則會把bean放入單例池
- 使用bean
- Spring容器關閉時調用DisposableBean中destory()方法
-
京東二面:Spring用到了哪些設計模式
-
談談你對AOP的理解
系統是由許多不同的組件所組成的,每一個組件各負責一塊特定功能。除了實現自身核心功能之外,這些組件還經常承擔著額外的職責。例如日志、事務管理和安全這樣的核心服務經常融入到自身具有核心業務邏輯的組件中去。這些系統服務經常被稱為橫切關注點,因為它們會跨越系統的多個組件。
當我們需要為分散的對象引入公共行為的時候,OOP則顯得無能為力。也就是說,OOP允許你定義從上到下的關系,但并不適合定義從左到右的關系。例如日志功能。
日志代碼往往水平地散布在所有對象層次中,而與它所散布到的對象的核心功能毫無關系。
在OOP設計中,它導致了大量代碼的重復,而不利于各個模塊的重用。
AOP:將程序中的交叉業務邏輯(比如安全,日志,事務等),封裝成一個切面,然后注入到目標對象(具體業務邏輯)中去。AOP可以對某個對象或某些對象的功能進行增強,比如對象中的方法進行增強,可以在執行某個方法之前額外的做一些事情,在某個方法執行之后額外的做一些事情