Java面試題:你知道Spring的IOC嗎?那麼,它為什麼這麼重要呢?

猫鱼吐泡泡發表於2024-04-28

Spring的IOC(控制反轉)是一種設計模式,它允許開發者將物件的建立和管理交給Spring框架來完成。在Spring中,IOC允許開發者將物件依賴關係從程式碼中分離出來,從而使程式碼更加靈活、可重用和易於管理。

IoC 全稱Inverse of Control(反向控制或控制反轉)。

在類和類之間存在控制權,控制權指的是物件的建立和使用,比如有類A和類B,我們之前的做法是在A中呼叫B,那麼控制權就在A中,這樣做的耦合度較高,如果修改了 B,A也要做相應修改。

class A {

} 

class B {
  // B需要將A的例項new出來,也就是我們說的控制 private A a = new A();
  public void use() {      
    System.out.print(a);
  }
}

引入Spring框架後,控制權由 spring 容器來負責。當A想使用B時,需要由 Spirng容器透過配置檔案進行注入。這種思想就是IoC(為了更好的理解,我們可以這樣認為,物件建立和使用的控制權轉移到了Spring容器,由Spring容器來控制)。

// 說明A自己控制自己,把自己初始化出來,注入給了容器 
@Component 
class A {

}

class B {
   // B不需要控制a,直接使用。如果A沒有把自己注入給容器,B就不能使用
   @Resource private A a;

   public void use() {
        System.out.print(a);
   }
}

實現Spring的IOC(控制反轉)有以下幾種方式

  • 使用@Autowired註解:這是Spring中最常用的實現IOC的方式。透過在需要依賴注入的類上使用@Autowired註解,Spring會自動將依賴物件注入到該類中。

  • 使用配置檔案:透過在Spring配置檔案中定義bean,可以手動建立和管理物件。這種方式適合於需要靈活控制物件建立和生命週期的情況。

  • 使用Java配置:透過使用Java配置類,可以更靈活地定義bean和配置物件之間的關係。這種方式適合於需要更細粒度控制的情況。

如何實現一個簡易的IOC功能?

上述是Spring容器簡單的使用IOC功能,如果我們自己想實現一個簡單版的,可以按照以下步驟:

  • 定義一個容器類,用於管理物件的建立和注入。

  • 實現物件的建立方法,可以使用常見的工廠模式或依賴查詢等方式來建立物件。

  • 在容器類中定義一個注入方法,用於將物件注入到需要依賴的物件中。


下面是一個簡單的程式碼示例,展示瞭如何實現一個簡易的IOC功能:

// 定義容器類
public class ObjectContainer {
  // 建立物件的方法
  public static Object createObject(String className) throws Exception {
    // 使用反射建立物件
    return Class.forName(className).newInstance();
  }

  // 注入物件的方法
  public static void injectObject(Object target, String className) throws Exception {
    // 將物件注入到目標物件中
    Field field = target.getClass().getField(className);
    field.set(target, ObjectContainer.createObject(className));
  }
}

// 使用示例
public class ExampleClass {
  private Object obj; // 需要注入的物件

  public ExampleClass(String className) {
    try {
      // 注入物件
      ObjectContainer.injectObject(this, className);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void doSomething() {
    // 使用物件進行操作
    obj.method();
  }
}

在上面的示例中,我們定義了一個ObjectContainer類,它包含了建立物件和注入物件的方法。在ExampleClass中,我們使用了ObjectContainer的注入方法將物件注入到目標物件中。使用時只需要傳入物件的類名即可。

請注意,上述示例只是一個簡單的實現,沒有考慮一些複雜的場景,例如迴圈依賴、型別轉換等問題。在實際開發中,需要根據具體的需求和場景進行適當的調整和最佳化。

使用IOC有哪些好處?

①、使用者不用關心引用Bean的實現細節,譬如對於B b = new A(c,d,e,f);來說,如果B要使用A,那還要 把c,d,e,f侈個類全都感知一遍,這顯然是非常麻煩且不合理的。

②、不用建立多個相同的bean導致浪費,仍然是:

A b = new A();
A c = new A();

如果B和C都引用了A,那麼B和C就可能new兩個A例項,實際上,我們只需要一個就好了。

③、Bean的修改使用方無需感知。同樣是上面的例子,假如說Bean A需要修改,如果沒有IOC的話,所有引用到A的其他Bean都需要感知這個邏輯,並且做對應的修改。但是如果使用了IOC,其他Bean就完全不用感知到。

往期面試題:

Java面試題:SimpleDateFormat是執行緒安全的嗎?使用時應該注意什麼?

Java面試題:細數ThreadLocal大坑,記憶體洩露本可避免

Java面試題:請談談對ThreadLocal的理解?

Java面試題:為什麼HashMap不建議使用物件作為Key?

相關文章