好程序員Java乾貨分享Spring框架之IOC原理

好程序員Java乾貨分享Spring框架之IOC原理,前言:Spring框架是咱們進行企業級開發的最經常使用框架,本章咱們將瞭解Spring框架,並學習Spring的IOC特性以及IOC的實現原理:註解和反射。程序員

Spring框架簡介

Spring是一種輕量級的控制反轉(IOC)和麪向切面編程(AOP)的容器框架,可以爲企業級開發提供一站式服務。web

Spring的優勢有數據庫

1.方便解耦,簡化開發編程

  經過Spring提供的IoC容器,咱們能夠將對象之間的依賴關係交由Spring進行控制,避免硬編碼所形成的過分程序耦合。有了Spring,用戶沒必要再爲單實例模式類、屬性文件解析等這些很底層的需求編寫代碼,能夠更專一於上層的應用。框架

2.AOP編程的支持工具

  經過Spring提供的AOP功能,方便進行面向切面的編程,許多不容易用傳統OOP實現的功能能夠經過AOP輕鬆應付。學習

3.聲明式事務的支持測試

  在Spring中,咱們能夠從單調煩悶的事務管理代碼中解脫出來,經過聲明式方式靈活地進行事務的管理,提升開發效率和質量。編碼

4.方便程序的測試spa

  能夠用非容器依賴的編程方式進行幾乎全部的測試工做,在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兩種

  1. /**
  2.  * CPU接口
  3.  */
  4. public interface Cpu {
  5.  
  6.     void run();
  7. }
  8. /**
  9.  * 內存接口
  10.  */
  11. public interface Memory {
  12.  
  13.     void read();
  14.     void write();
  15. }
  16. /**
  17.  * AMD的CPU
  18.  */
  19. public class AMDCpu implements Cpu {
  20.  
  21.     public void run() {
  22.         System.out.println("AMD的CPU正在運行....");
  23.     }
  24. }
  25. /**
  26.  * Intel的CPU
  27.  */
  28. public class IntelCpu implements Cpu{
  29.  
  30.     public void run() {
  31.         System.out.println("Intel的CPU正在運行....");
  32.     }
  33. }
  34. /**
  35.  * DDR8G的內存
  36.  */
  37. public class DDR8GMemory implements Memory {
  38.     public void read() {
  39.         System.out.println("使用DDR8G的內存讀取數據....");
  40.     }
  41.  
  42.     public void write() {
  43.         System.out.println("使用DDR8G的內存寫入數據....");
  44.     }
  45. }
  46. /**
  47.  * DDR16G的內存
  48.  */
  49. public class DDR16GMemory implements Memory {
  50.     public void read() {
  51.         System.out.println("使用DDR16G的內存讀取數據....");
  52.     }
  53.  
  54.     public void write() {
  55.         System.out.println("使用DDR16G的內存寫入數據....");
  56.     }
  57. }
  58. public class TestComputer {
  59.  
  60.     @Test
  61.     public void testComputer(){
  62.         //硬編碼方式建立對象
  63.         Computer computer = new Computer();
  64.         Cpu cpu = new IntelCpu();
  65.         Memory memory = new DDR16GMemory();
  66.         computer.setCpu(cpu);
  67.         computer.setMemory(memory);
  68.         computer.start();
  69.     }
  70. }

 

上面是使用硬編碼方式建立電腦的CPU和內存屬性,代碼和具體的子類緊密耦合,不利於後期的維護和擴展。

修改的思路是:不禁讓程序主動建立去建立CPU和內存對象,而是經過註解方式標記CPU和內存的類型,使用反射將CPU和內存的對象注入到電腦的屬性中。

添加代碼:

  1. /**
  2.  * 電腦組件的註解
  3.  */
  4. @Retention(RetentionPolicy.RUNTIME)
  5. @Target(ElementType.FIELD)
  6. public @interface MyComponent {
  7.     /**
  8.      * 組件類型
  9.      * @return
  10.      */
  11.     Class componentClass();
  12. }
  13. /**
  14.  * 電腦類
  15.  */
  16. public class Computer {
  17.  
  18.     @MyComponent(componentClass = IntelCpu.class)
  19.     private Cpu cpu;
  20.  
  21.     @MyComponent(componentClass = DDR8GMemory.class)
  22.     private Memory memory;
  23.  
  24. ....}
  25.  
  26. public class TestComputer {
  27.  
  28.     @Test
  29.     public void testComputer(){
  30.         //經過反射和註解,將cpu和memory屬性注入進去
  31.         try {
  32.             //得到Computer類型
  33.             Class<Computer> computerClass = Computer.class;
  34.             //建立Computer對象
  35.             Computer computer = computerClass.newInstance();
  36.             //得到Computer對象的屬性
  37.             Field[] fields = computerClass.getDeclaredFields();
  38.             //遍歷屬性
  39.             for(Field field : fields){
  40.                 //得到屬性上定義的MyComponent註解
  41.                 MyComponent anno = field.getDeclaredAnnotation(MyComponent.class);
  42.                 //得到配置的組件類型
  43.                 Class aClass = anno.componentClass();
  44.                 //建立該組件的對象
  45.                 Object comp = aClass.newInstance();
  46.                 //調用set方法賦值給屬性
  47.                 String name = field.getName();
  48.                 name = "set" + name.substring(0,1).toUpperCase() + name.substring(1);
  49.                 //經過方法名和參數類型得到方法
  50.                 Method method = computerClass.getDeclaredMethod(name, field.getType());
  51.                 //調用方法
  52.                 method.invoke(computer,comp);
  53.             }
  54.             //啓動電腦
  55.             computer.start();
  56.         } catch (Exception e) {
  57.             e.printStackTrace();
  58.         }
  59.     }
  60. }

程序如上面修改後,後期若是須要修改電腦的配置,只須要修改註解配置的類型,就能夠注入不一樣的電腦組件,這樣就下降了代碼間的耦合性,維護代碼變得比較簡單。

  @MyComponent(componentClass = AMDCpu.class)

    private Cpu cpu;

 

  @MyComponent(componentClass = DDR16GMemory.class)

   private Memory memory;

總結

IOC(控制反轉)是Spring最重要的原理,它將建立對象的主動權交給Spring容器,Spring程序只須要進行一些配置,就可使用不一樣的對象,極大的下降了代碼耦合性,提升了程序的靈活性,IOC的實現原理是反射機制。

相關文章
相關標籤/搜索