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

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?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章