跳转至

IoC (Inversion of Controll 控制反轉)

將 Object 的控制權交給了外部的 Spring 容器來統一管理

優點: 1. Loose coupling 鬆耦合

原本 Teacher 跟 HpPrinter 的關聯性較高

public class Teacher{
    private Printer printer = new HpPrinter();
    public void teach(){
        printer.print("I'm a teacher");
    }
}

Spring 容器控管印表機 ,Teacher 跟 HpPrinter的關聯性降低

public class Teacher{
    private Printer printer;
    public void teach(){
        printer.print("I'm a teacher");
    }
}
  1. Lifecycle Management 生命週期管理

XXPrinter 創建 ,初始化 ,銷毀

public class Teacher{
    private Printer printer;
}
  1. more testable 方便測試程式

@Component 將該 class 變成由 Spring 容器所管理的 object

Spring 就會幫我們創建一個Bean hpPrinter 這個object放在 Spring Container 這個容器

@Component
public class HpPrinter implements Printer{
    @Override
    public void print(String msg){
        System.out.println("HP印表機: " + msg );
    }
}

@Component 這個註解只能加在class上面

bean是什麼? Spring 框架裡面才有的專有名詞 , 存放在Spring 容器裡面的 object

bean的名字? class name的第一個字母會轉為小寫

:::success Bean hpPrinter 跟 Printer printer = new HpPrinter(); 相同嗎? 錯

Printer printer = new HpPrinter(); 它只是在普通的Java代碼中初始化一個對象。

在Spring框架中使用Bean,需要通過Spring的IoC容器來配置和獲取這些Bean。 :::

怎麼 bean

// 步驟1
// 將HpPrinter 存放到Spring 容器 得到Bean hpPrinter 
@Component
public class HpPrinter implements Printer{
    @Override
    public void print(String msg){
        System.out.println("HP印表機: " + msg );
    }
}

// 步驟2
// 將Teacher 也變成bean
@Component
public class Teacher{
    // 步驟3
    @Autowired 
    private Printer printer;
    public void teach(){
        printer.print("I'm a teacher");
    }
}

當在某個變數加上@Autowired ,Spring 容器就會把你想要的bean交給你

dependency Injection 依賴注入 (DI)

將teacher 依賴的東西交給他

bean的練習

package com.example.demo;

public interface Printer {
    void print(String msg);
}
package com.example.demo;

import org.springframework.stereotype.Component;

@Component
public class HpPrinter implements Printer{

    @Override
    public void print(String msg) {
        System.out.println("Hp印表機: " + msg);
    }

}
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @Autowired
    private Printer printer;

    @RequestMapping("/test")
    public String test() {
        printer.print("Hello");
        return "hello world";
    }
} 

為甚麼 MyController 沒有 @Component 卻還是可以使用 @Autowired private Printer printer;

因為 @RestController 也是創建bean的一種方式