Spring是一個(gè)開源框架, 為了簡化企業(yè)級復(fù)雜應(yīng)用開發(fā)而生, 是一個(gè)IOC容器。
IOC(Inversion of Control) : 其實(shí)質(zhì)是反轉(zhuǎn)獲取資源的方向。
? ? ?a、傳統(tǒng)的方式是當(dāng)前組件向容器發(fā)出獲取資源的請求, 容器返回組件所需的資源, 當(dāng)前組件得到資源,并使用。
? ? ?b、引入IOC技術(shù)后, 容器向自己所管理的組件推送組件所需的資源, 各個(gè)組件根據(jù)自身的需求適時(shí)地接收資源,并使用。
? ? c、這些資源怎么生成的呢??在組件程序啟動(dòng)時(shí), spring框架通過XML 配置, 注解或是Java configuration事先創(chuàng)建這些資源, 并適時(shí)地推送給組件, 組件接收到資源后使用。
為什么需要IOC?
1、應(yīng)用程序主動(dòng)控制對象的實(shí)例化和對象間的依賴裝配。
Car mycar = new Car();
Motor mymotor = new Motor();
mycar.setMotor(mymotor);
本質(zhì):程序主動(dòng)實(shí)例化,直接獲取依賴, 直接裝配依賴。
缺點(diǎn):生產(chǎn)者和消費(fèi)者相互耦合, 難于更換實(shí)現(xiàn)(更改需要重新編譯代碼),難于測試。
2、引進(jìn)簡單工廠類
Car mycar = CarFactory.CreateCar();
Motor mymotor = MotorFactory.CreateMotor();
mycar.setMotor(mymotor);
本質(zhì):對象創(chuàng)建,間接實(shí)例化(工廠),間接獲取依賴(工廠), 直接裝配依賴。
缺點(diǎn):難于更換實(shí)現(xiàn)(更改需要重新編譯代碼),難于測試。
3、引進(jìn)可配置工廠
Car mycar = Factory.CreateCar("CarBean");
<!--XML配置文件>
<bean ?id = "CarBean" Class = "Car"
< property name = "myMotor" ref = "MotorBean" />
/bean>
<bean id= "MotorBean" class = "Motor" />
本質(zhì): 對象創(chuàng)建, 被動(dòng)實(shí)例化,被動(dòng)獲取依賴,被動(dòng)裝配依賴(全由工廠負(fù)責(zé),工廠控制)。
缺點(diǎn): 不通用
程序步驟:
a、工廠讀取XML文件, 通過JAVA reflect 創(chuàng)建Car對象;
b、創(chuàng)建時(shí)發(fā)現(xiàn)Car對象有屬性myMotor
c、讀取XML文件, 通過JAVA reflect創(chuàng)建Motor對象
d、將myMotor裝配到Car對象
e、返回實(shí)例化以及裝配完成的Car對象。
4、IOC容器,容器控制對象的實(shí)例化和依賴裝配, 類似于可配置的工廠類,只是更通用了。
Car mycar = applicationContext.getBean("CarBean");
<!--XML配置文件>
<bean id = "CarBean" class = "Car"
< property name = "myMotor" ref = "MotorBean" >
/bean>
< bean id = "MotorBean" class = "Motor" />
本質(zhì): 對象創(chuàng)建, 被動(dòng)實(shí)例化,被動(dòng)獲取依賴,被動(dòng)裝配依賴(工廠,反射, XML配置), 對象的生命周期的管理。
DI(Dependency Injection) : IOC的實(shí)現(xiàn)方式:即組件以一些預(yù)先定義好的方式(如: setter, getter方法)接受來自如容器的資源注入。其實(shí)現(xiàn)方式主要包括如下:
? ? 1、構(gòu)造器注入
? ? 2、屬性setter注入
? ? 3、接口注入