Spring框架的核心就是控制反轉(zhuǎn)(Inversion of Control)和依賴注入(Dependency Injection),通過這兩方面來實(shí)現(xiàn)松耦合。
??? 使用IoC,對象是被動的接受依賴類,而不是自己主動的去找。容器在實(shí)例化的時候主動將它的依賴類注入給它。可以這樣理解:控制反轉(zhuǎn)將類的主動權(quán)轉(zhuǎn)移到接口上,依賴注入通過xml配置文件在類實(shí)例化時將其依賴類注入。通過下面的實(shí)例來逐步的理解:
??? 首先假設(shè)有一個需求,類Business需要調(diào)用類Dependency的方法f(),按照日常的做法,得到下面的代碼:
//**類Dependency**
public class Dependency {
??? public void f() {};
}
//**類Business**
public? class Business {
??? Dependency d;
??? public Business() {
??? d = new Dependency();
??? }
??? public void doSth() {
??????? d.f();
??? }
}
??? 對上述實(shí)現(xiàn)做出如下修改:
??? 首先,將Business里的Dependency實(shí)例的獲得該為setter方式,其次,將Dependency類改為某個接口的實(shí)現(xiàn)。故可以得到下面新的代碼:
//**接口IDependency**
public inte***ce IDependency {
??? void f();
}
//**類Dependency**
public class Dependency {
??? public void f() {};
}
//**類Business**
public? class Business {
??? IDependency d;
??? public Business() {}
??? public void doSth() {
???? d.f();
??? }
??? public void setDependency(IDependency d) {
??????? this.d = d;
??? }
}
??? 在新的代碼中,首先Business的變量d可以接收任何IDependency的實(shí)例,另外,Dependency的實(shí)例不是通過Business來獲得,而是通過setter(也可以用構(gòu)造器)來由外部傳給它。這似乎跟我們往常的代碼沒什么不同,但這已經(jīng)是一個良好的設(shè)計。關(guān)鍵就是Dependency的實(shí)例如何從外部注入給Business呢?
這就要通過xml來實(shí)現(xiàn)了。
??? 創(chuàng)建一個SpringFirst.xml,進(jìn)行簡單的配置:
<beans>
??? <bean id = "dependency" class = "aopfirst.business.Dependency" />
??? <bean
??????? id = "business"
??????? class = "aopfirst.business.Business"
??? >
??????? <property name = "dependency">
??????????? <ref bean = "dependency" />
??????? </property>
??? </bean>
</beans>
??? 這個配置文件里將Dependency類和Business類加入,并將Dependency作為Business的一個參數(shù)。
??? 單有了這個xml文件還不夠,還需要一個測試類來加載該xml文件,spring提供了現(xiàn)成的API,在加載上面的xml的時候,就進(jìn)行了如下工作:實(shí)例化Dependency類,實(shí)例化Business類,并將Dependency的實(shí)例作為參數(shù)賦給了Business實(shí)例的
setDependency()方法。下面是該測試程序:
public class StartServer {
??? public static void main(String [] args) {
???? ClassPathResource cr = new ClassPathResource("SpringFirst.xml");
???? BeanFactory factory = new XmlBeanFactory(cr);
???? Business b = (Business)factory.getBean("business");
???? b.doSth();
??? }
}
??? 上面的程序加載了xml以后,獲得id為"business"的bean,即Business類的實(shí)例,并調(diào)用了其doSth()方法。由此可見,Business的依賴類Dependency是通過xml來注入的,而且Business是通過接口IDependency來接收Dependency實(shí)例。因此,當(dāng)我們又有新的IDependency的實(shí)現(xiàn)時,只需要修改xml文件即可,測試程序只需要根據(jù)xml里的id值來獲得需要的參數(shù)。
??? 總結(jié)上面的例子,對控制反轉(zhuǎn)和依賴注入已經(jīng)能理解了。依賴類(Dependency)是通過外部(xml)來注入的,而不是由使用它的類(Business)來自己制造,這就是依賴的注入。另一方面,Business對類Dependency的依賴轉(zhuǎn)移到對接口IDependency的依賴,控制權(quán)由類轉(zhuǎn)移到了接口,即由"實(shí)現(xiàn)"轉(zhuǎn)移到"抽象"中。這就是控制反轉(zhuǎn)。