Try   HackMD

Spring IoC Container 學習筆記

contributed by < jeffrey.w >

Background

有什麼方法可以對一個物件的 property 指定不同的 value,卻不用修改 程式?當我們在實作 function 的時候還不知道某一個物件的值是什麼,有什麼方法可以把「指定一個特定的值」這件事放在 source code 的外部?有什麼方法可以「不用修改程式就能把某一個變數所 reference 到的物件換成另一份 implementation」?

這個時候就可以使用 IoC (Inversion of Control) 了,而實現 IoC 的方式之一就是 DI (Dependency Injection)。透過 DI,當需要指定不同的值給 property 或是使用不同的 implementation 的時候,就不用對 source code 重新 compile,只需要更改依賴注入就可以注入不一樣的 implementation 和 property。

BeanFactory

在寫這段 code 的時候,還不知道 cpu.printVendor(); 會印出什麼,但是可以 從外部提供一個 implementation,而不用修改 source code,這個從外部提供的動作就是依賴注入 Dependency Injection

在這個例子 CPU 是一個 interface,第 3 行這麼寫是基於 Liskov Substitution Principle,所以使用 interface。而 factory.getBean("cpu"); 會返回一個 implements CPU 的物件。

所以,寫下以下這幾行的時候,可以不用知道有一個 com.test.ioc.CortexA15 這種 class 的存在,這就代表未來如果增加了 com.test.ioc.PowerPC 或是 com.test.ioc.CortexA53 或是其他 class,以下這幾行都可以不用再修改,只需要透過 Dependency Injection 就可以更換成不同的 implementation。

XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource("beans.xml")); CPU cpu = (CPU) factory.getBean("cpu"); cpu.printVendor();

CPU.java

package com.test.ioc;

public interface CPU {
    void printVendor();
}

CortexA15.java

package com.test.ioc;

public class CortexA15 implements CPU {
    private String vendor;

    public void setVendor(String vendor){
        this.vendor = vendor;
    }

    @Override
    public void printVendor() {
        System.out.println(this.vendor);
    }
}

beans.xml
改變第 8 行就可以直接指定 context.getBean("cpu"); 所返回的物件是哪一種 implementation。
改變第 9 行就可以指定 vendor 這個 property 的值而 不用修改程式

<?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"> <bean id="cpu" class="com.test.ioc.CortexA15"> <property name="vendor" value="Arm"/> </bean> </beans>

也就是說,在這個例子裡,不用修改程式,也不用重新 compile,只要修改 beans.xml 就可以注入不一樣的 implementation 和不一樣的 property

修改 beans.xml 之後,執行以下這個 command

$ mvn spring-boot:run

因為 source code 沒有改到,所以不會重新 compile

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

source code 的 tree-like format

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Reference

tags: java spring ioc container Inversion of Control Dependency Injection