好程式設計師Java乾貨分享Spring框架之IOC原理
好程式設計師 Java 乾貨分享 Spring 框架之 IOC 原理, 前言:Spring 框架是我們進行企業級開發的最常用框架,本章我們將瞭解 Spring 框架,並學習 Spring 的 IOC 特性以及 IOC 的實現原理:註解和反射。
Spring 框架簡介
Spring 是一種輕量級的控制反轉( IOC )和麵向切面程式設計( AOP )的容器框架,能夠為企業級開發提供一站式服務。
Spring 的優點有
1. 方便解耦,簡化開發
透過 Spring 提供的 IoC 容器,我們可以將物件之間的依賴關係交由 Spring 進行控制,避免硬編碼所造成的過度程式耦合。有了 Spring ,使用者不必再為單例項模式類、屬性檔案解析等這些很底層的需求編寫程式碼,可以更專注於上層的應用。
2.AOP 程式設計的支援
透過 Spring 提供的 AOP 功能,方便進行面向切面的程式設計,許多不容易用傳統 OOP 實現的功能可以透過 AOP 輕鬆應付。
3. 宣告式事務的支援
在 Spring 中,我們可以從單調煩悶的事務管理程式碼中解脫出來,透過宣告式方式靈活地進行事務的管理,提高開發效率和質量。
4. 方便程式的測試
可以用非容器依賴的程式設計方式進行幾乎所有的測試工作,在 Spring 裡,測試不再是昂貴的操作,而是隨手可做的事情。例如: Spring 對 Junit4 支援,可以透過註解方便的測試 Spring 程式。
5. 方便整合各種優秀框架
Spring 不排斥各種優秀的開源框架,相反, Spring 可以降低各種框架的使用難度, Spring 提供了對各種優秀框架(如 Struts,Hibernate 、 Hessian 、 Quartz )等的直接支援。
6. 降低 Java EE API 的使用難度
Spring 對很多難用的 Java EE API (如 JDBC , JavaMail ,遠端呼叫等)提供了一個薄薄的封裝層,透過 Spring 的簡易封裝,這些 Java EE API 的使用難度大為降低。
Spring 的組成
Spring Core : Spring 框架的核心。 Spring 其它元件都依賴於核心元件,主要透過 BeanFactory 提供 IOC 等服務。
Spring Context : Sprin 上下文是一個配置檔案,向 Spring 框架提供上下文資訊。 Spring 上下文包括企業服務,例如 JNDI 、 EJB 、電子郵件、國際化、校驗和排程功能。
Spring AOP :透過配置管理特性, Spring AOP 模組直接將面向切面的程式設計功能整合到了 Spring 框架中。
Spring ORM : Spring 框架插入了若干個 ORM 框架,從而提供了 ORM 的物件關係工具,其中包括 JDO 、 Hibernate 和 iBatisSQL Map 。所有這些都遵從 Spring 的通用事務和 DAO 異常層次結構。
Spring DAO: DAO 抽象層提供了有意義的異常層次結構,可用該結構來管理異常處理和不同資料庫供應商丟擲的錯誤訊息。異常層次結構簡化了錯誤處理,並且極大地降低了需要編寫的異常程式碼數量(例如開啟和關閉連線)。 Spring DAO 的面向 JDBC 的異常遵從通用的 DAO 異常層次結構。
Spring Web: Web 上下文模組建立在應用程式上下文模組之上,為基於 Web 的應用程式提供了上下文。所以, Spring 框架支援與 Jakarta Struts 的整合。 Web 模組還簡化了處理多部分請求以及將請求引數繫結到域物件的工作。
Spring Web MVC: 為 web 應用提供了模型檢視控制( MVC )和 REST Web 服務的實現。 Spring 的 MVC 框架可以使領域模型程式碼和 web 表單完全地分離,且可以與 Spring 框架的其它所有功能進行整合。
IOC 和 DI
IOC ( Inverse Of Control )是控制反轉的意思,作用是降低物件之間的耦合度。
一般情況下我們直接在物件內部透過 new 進行建立物件,是程式主動去建立依賴物件;而 IoC 是有專門一個容器來建立這些物件,即由 Ioc 容器來控制物件的建立;這樣就是由容器來控制物件,而不是由我們的物件來控制,這樣就完成了控制反轉。
DI(Dependency Injection )即“依賴注入”:是元件之間依賴關係由容器在執行期決定,形象的說,即由容器動態的將某個依賴關係注入到元件之中。依賴注入的目的並非為軟體系統帶來更多功能,而是為了提升元件重用的頻率,併為系統搭建一個靈活、可擴充套件的平臺。透過依賴注入機制,我們只需要透過簡單的配置,而無需任何程式碼就可指定目標需要的資源,完成自身的業務邏輯,而不需要關心具體的資源來自何處,由誰實現。
IOC 的原理:註解 + 反射
下面的案例講解了 IOC 的原理,模擬為電腦配置不同的 CPU 和記憶體, CPU 有 AMD 和 INTEL 兩種,記憶體有 DDR8G 和 DDR16G 兩種
- /**
- * CPU 介面
- */
- public interface Cpu {
- void run();
- }
- /**
- * 記憶體介面
- */
- public interface Memory {
- void read();
- void write();
- }
- /**
- * AMD 的 CPU
- */
- public class AMDCpu implements Cpu {
- public void run() {
- System.out.println("AMD 的 CPU 正在執行 ....");
- }
- }
- /**
- * Intel 的 CPU
- */
- public class IntelCpu implements Cpu{
- public void run() {
- System.out.println("Intel 的 CPU 正在執行 ....");
- }
- }
- /**
- * DDR8G 的記憶體
- */
- public class DDR8GMemory implements Memory {
- public void read() {
- System.out.println(" 使用 DDR8G 的記憶體讀取資料 ....");
- }
- public void write() {
- System.out.println(" 使用 DDR8G 的記憶體寫入資料 ....");
- }
- }
- /**
- * DDR16G 的記憶體
- */
- public class DDR16GMemory implements Memory {
- public void read() {
- System.out.println(" 使用 DDR16G 的記憶體讀取資料 ....");
- }
- public void write() {
- System.out.println(" 使用 DDR16G 的記憶體寫入資料 ....");
- }
- }
- public class TestComputer {
- @Test
- public void testComputer(){
- // 硬編碼方式建立物件
- Computer computer = new Computer();
- Cpu cpu = new IntelCpu();
- Memory memory = new DDR16GMemory();
- computer.setCpu(cpu);
- computer.setMemory(memory);
- computer.start();
- }
- }
上面是使用硬編碼方式建立電腦的 CPU 和記憶體屬性,程式碼和具體的子類緊密耦合,不利於後期的維護和擴充套件。
修改的思路是:不由讓程式主動建立去建立 CPU 和記憶體物件,而是透過註解方式標記 CPU 和記憶體的型別,使用反射將 CPU 和記憶體的物件注入到電腦的屬性中。
新增程式碼:
- /**
- * 電腦元件的註解
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface MyComponent {
- /**
- * 元件型別
- * @return
- */
- Class componentClass();
- }
- /**
- * 電腦類
- */
- public class Computer {
- @MyComponent(componentClass = IntelCpu.class)
- private Cpu cpu;
- @MyComponent(componentClass = DDR8GMemory.class)
- private Memory memory;
- ....}
- public class TestComputer {
- @Test
- public void testComputer(){
- // 透過反射和註解,將 cpu 和 memory 屬性注入進去
- try {
- // 獲得 Computer 型別
- Class<Computer> computerClass = Computer.class;
- // 建立 Computer 物件
- Computer computer = computerClass.newInstance();
- // 獲得 Computer 物件的屬性
- Field[] fields = computerClass.getDeclaredFields();
- // 遍歷屬性
- for(Field field : fields){
- // 獲得屬性上定義的 MyComponent 註解
- MyComponent anno = field.getDeclaredAnnotation(MyComponent.class);
- // 獲得配置的元件型別
- Class aClass = anno.componentClass();
- // 建立該元件的物件
- Object comp = aClass.newInstance();
- // 呼叫 set 方法賦值給屬性
- String name = field.getName();
- name = "set" + name.substring(0,1).toUpperCase() + name.substring(1);
- // 透過方法名和引數型別獲得方法
- Method method = computerClass.getDeclaredMethod(name, field.getType());
- // 呼叫方法
- method.invoke(computer,comp);
- }
- // 啟動電腦
- computer.start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
程式如上面修改後,後期如果需要修改電腦的配置,只需要修改註解配置的型別,就可以注入不同的電腦元件,這樣就降低了程式碼間的耦合性,維護程式碼變得比較簡單。
@MyComponent(componentClass = AMDCpu.class)
private Cpu cpu;
@MyComponent(componentClass = DDR16GMemory.class)
private Memory memory;
總結
IOC (控制反轉)是 Spring 最重要的原理,它將建立物件的主動權交給 Spring 容器, Spring 程式只需要進行一些配置,就可以使用不同的物件,極大的降低了程式碼耦合性,提高了程式的靈活性, IOC 的實現原理是反射機制。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2649996/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師Java培訓分享Spring Ioc的原理程式設計師JavaSpring
- 好程式設計師java分享spring框架精講程式設計師JavaSpring框架
- 好程式設計師Java分享Spring框架之AOP的基本配置程式設計師JavaSpring框架
- Java必備乾貨:Spring框架之IOC的基本配置JavaSpring框架
- 好程式設計師Java教程分享javaweb框架程式設計師JavaWeb框架
- 好程式設計師Java教程分享Java之設計模式程式設計師Java設計模式
- 好程式設計師web前端乾貨之web前端開發框架彙總程式設計師Web前端框架
- 好程式設計師Java學習路線分享MyBatis之Spring整合程式設計師JavaMyBatisSpring
- 好程式設計師Java教程分享Java開發主流框架程式設計師Java框架
- 好程式設計師Java乾貨分享5分鐘瞭解折半插入排序程式設計師Java排序
- 好程式設計師Java學習路線之Spring框架之動態代理程式設計師JavaSpring框架
- 好程式設計師分享自學大資料入門乾貨程式設計師大資料
- 好程式設計師Java教程分享幾個流行的Java框架程式設計師Java框架
- 好程式設計師分享java設計模式之享元模式程式設計師Java設計模式
- 好程式設計師Java分享SpringMVC之@ResponseBody註解程式設計師JavaSpringMVC
- 好程式設計師分享乾貨 彈性分散式資料集RDD程式設計師分散式
- Spring框架系列(6) - Spring IOC實現原理詳解之IOC體系結構設計Spring框架
- 好程式設計師Java培訓分享Java程式設計技巧程式設計師Java
- 好程式設計師Java教程分享Java面試題之Hibernate程式設計師Java面試題
- 好程式設計師Java培訓分享Java之反射技術程式設計師Java反射
- 好程式設計師Java培訓分享SpringBoot -自動配置原理程式設計師JavaSpring Boot
- 好程式設計師Java教程分享Vue外掛之Axios程式設計師JavaVueiOS
- 好程式設計師Java分享MySQL之SQL入門(一)程式設計師JavaMySql
- 好程式設計師Java學習路線分享Java框架怎麼搭建程式設計師Java框架
- 好程式設計師Java培訓分享Java程式設計師技能提升指南程式設計師Java
- 好程式設計師大資料學習路線之zookeeper乾貨程式設計師大資料
- 好程式設計師Java教程分享Java難點解析之泛型程式設計師Java泛型
- 好程式設計師Java教程分享Java語法程式設計師Java
- 好程式設計師大資料學習路線Hadoop學習乾貨分享程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享hdfs學習乾貨程式設計師大資料
- 好程式設計師Java教程分享List介面程式設計師Java
- 好程式設計師Java培訓分享Java的三大框架怎麼學?程式設計師Java框架
- 好程式設計師Java教程分享Java之包裝類與常用類程式設計師Java
- 好程式設計師Java培訓分享Java程式設計師常用的工具類庫程式設計師Java
- 好程式設計師Java培訓分享20個Java程式設計師基礎題程式設計師Java
- 好程式設計師Java教程分享Java面試妙招程式設計師Java面試
- 好程式設計師Java教程分享Java開發工具程式設計師Java
- 好程式設計師Java培訓分享註解與反射原理說明程式設計師Java反射