內部最核心的就是IOC了,直觀地講,就是容器控制程序之間的關係,而非傳統實現中,由程序代碼直接操控。這也就是所謂「控制反轉」的概念所在。控制權由應用代碼中轉到了外部容器,控制權的轉移是所謂反轉。html
IoC還有另一個名字——「依賴注入(Dependency Injection)」。從名字上理解,所謂依賴注入,即組件之間的依賴關係由容器在運行期決定,形象地說,即由容器動態地將某種依賴關係注入到組件之中。java
依賴注入的三種實現類型:接口注入、 Setter 注入和構造器注入。
web
一、接口注入spring
public class ClassA { private InterfaceB clzB; public void doSomething() { Ojbect obj =Class.forName(Config.BImplementation).newInstance(); clzB = (InterfaceB)obj; clzB.doIt() } …… }上面的代碼中, ClassA 依賴於 InterfaceB 的實現,如何得到 InterfaceB 實現類的實例?傳統的方法是在代碼中建立 InterfaceB 實現類的實例,並將起賦予 clzB 。 而這樣一來, ClassA 在編譯期即依賴於 InterfaceB 的實現。爲了將調用者與實現者在編譯期分離,因而有了上面的代碼. 咱們根據預先在配置文件中設定的實現類的類名 (Config.BImplementation) ,動態加載實現類,並經過 InterfaceB 強制轉型後爲 ClassA 所用。這就是接口注入的一個最原始的雛形。 而對於一個 接口 型 IOC 容器而言,加載接口實現並建立其實例的工做由容器完成,見以下代碼。
public class ClassA { private InterfaceB clzB; public Object doSomething(InterfaceB b) { clzB = b; return clzB.doIt(); } …… }在運行期, InterfaceB 實例將由容器提供。 接口型 IOC 發展較早(有意或無心),在實際中獲得了廣泛應用,即便在 IOC
public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException { …… } }上面的代碼應該有印象吧
二、Setter( 設值 ) 注入 數據庫
各類類型的依賴注入模式中,設值注入模式在實際開發中獲得了最普遍的應用。
編程
public class ClassA { private InterfaceB clzB; public void setClzB(InterfaceB clzB) { this. clzB = clzB; } …… }
這裏是TextEditor.java文件的內容:
架構
package com.yiibai; public class TextEditor { private SpellChecker spellChecker; // a setter method to inject the dependency. public void setSpellChecker(SpellChecker spellChecker) { System.out.println("Inside setSpellChecker." ); this.spellChecker = spellChecker; } // a getter method to return spellChecker public SpellChecker getSpellChecker() { return spellChecker; } public void spellCheck() { spellChecker.checkSpelling(); } }在這裏,須要檢查setter方法的命名約定。設置咱們使用setSpellChecker()方法,這是很是相似於Java POJO類的變量的拼寫檢查器。讓咱們創造另外一個相關的類文件SpellChecker.java,內容以下:
package com.yiibai; public class SpellChecker { public SpellChecker(){ System.out.println("Inside SpellChecker constructor." ); } public void checkSpelling() { System.out.println("Inside checkSpelling." ); } }如下是MainApp.java文件的內容:
package com.yiibai; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); TextEditor te = (TextEditor) context.getBean("textEditor"); te.spellCheck(); } }配置文件爲
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- Definition for textEditor bean --> <bean id="textEditor" class="com.yiibai.TextEditor"> <property name="spellChecker" ref="spellChecker"/> </bean> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.yiibai.SpellChecker"> </bean> </beans>
依賴關係是經過類構造函數創建的 容器經過調用類的構造方法將其所需的依賴關係注入其中 app
public class DIByConstructor { private final DataSource dataSource; public DIByConstructor(DataSource ds) { this.dataSource = ds; } …… }再以下例子:
在須要注入的類中,編寫注入的構造方法框架
public PersonServiceBean(PersonDao personDao, String string) { this.personDao = personDao; this.string = string; }在beans.xml中申明被注入的類
<bean id="personDao" class="com.dwt1220.PersonDaoBean" />在注入類的<bean>標籤體中使用<constructor-arg>標籤
<bean id="personService" class="com.dwt1220.PersonServiceBean"> <!--index=構造方法的參數位置(下標從0開始), type=注入的類型,ref=注入類在beans.xml中註冊的ID --> <constructor-arg index="0" type="com.dwt1220.PersonDao" ref="personDao"/> <constructor-arg index="1" value="dwt1220" /> </bean>PersonServiceBean.java類
package com.dwt1220; public class PersonServiceBean implements PersonService { private PersonDao personDao; private String string; public PersonServiceBean(PersonDao personDao, String string) { this.personDao = personDao; this.string = string; } public PersonDao getPersonDao() { return personDao; } public void setPersonDao(PersonDao personDao) { this.personDao = personDao; } public void save() { System.out.println("這是save方法"); System.out.println(string); } }beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="personDao" class="com.dwt1220.PersonDaoBean" /> <bean id="personService" class="com.dwt1220.PersonServiceBean"> <!--index=構造方法的參數位置(下標從0開始), type=注入的類型,ref=注入類在beans.xml中註冊的ID --> <constructor-arg index="0" type="com.dwt1220.PersonDao" ref="personDao"/> <constructor-arg index="1" value="dwt1220" /> </bean> </beans>Test.java
package com.dwt1220; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); PersonService personService = (PersonService) ctx.getBean("personService"); personService.save(); ctx.close(); } }
文件來動態的建立對象,和調用對象裏的方法的 。 yii
Spring它是一個開源的項目,並且目前很是活躍;它基於IoC(Inversion of Control,反向控制)和AOP的構架多層j2ee系統的框架,但它不強迫你必須在每一層 中必須使用Spring,由於它模塊化的很好,容許你根據本身的須要選擇使用它的某一個模塊;它實現了很優雅的MVC,對不一樣的數據訪問技術提供了統一的 接口,採用IoC使得能夠很容易的實現bean的裝配,提供了簡潔的AOP並據此實現Transcation Managment,等等