這只是個 interface 啊,它怎麼執行起來的?!
複習一下 interface
interface(介面),像是規格書、定義出該要有哪些 method;由 implement 它的 class(實作類別)去 override 這些 method、並把內容完成。
舉個例子,「List」是 interface、定義要有 add()
這個 method;而「ArrayList」和「LinkedList」implement 此 interface,分別用不同的實作方式實現了 add()
這個 method 所要有的功能。
interface 是不能用 new
產生出物件實例的,它只是規格書、不是藍圖;所以,當我們在 Spring Boot 的一個 Service class 裡注入了一個 Repository,它一定有一個實作的 class 本體……對吧?
範例
我有個 Entity class 名為 Game
,並其 primary key 的型別為 Integer
,因此我寫了一個 interface、繼承 Spring Data JPA 的 JpaRepository
:
public interface GameRepo extends JpaRepository<Game, Integer> {}
只有寫這樣,也沒有加上 @Repository
annotation。
在 service class,用 constructor DI 注入了這個 interface 的 Bean:
public class GameService { // ... private final GameRepo gameRepo;
public GameService(GameRepo gameRepo) { this.gameRepo = gameRepo; } // ...}
這樣就能直接使用了 O.O ——我沒有自己寫實作 class 哦?!
Spring 怎麼辦到的?——動態代理(Dynamic Proxy)
動態代理(Dynamic Proxy)是什麼?簡單來說,是在執行時動態地根據反射產生物件實例、而非根據寫好的 class 產生。
當 Spring Boot Application 啟動,會掃描所有繼承了 JpaRepository
的 interface、利用動態代理產生代理物件實例,並作為 Bean 給我們使用。
所以,我們自己沒有寫實作 class、是 Spring 幫我們做了個代理給我們用;並且,這個代理類別已經包含 @Repository
的功能,所以不用在我們自己寫的 repository interface 上面寫。
至於動態代理是怎麼實現的,還要先瞭解「反射」……就不在此細講了,因為我也還不是很懂。
怎麼知道它是代理?
對一個物件實例使用 getClass()
,可以得到一個 Class 物件,裡面有許多方法、可以取得關於這個 class 的相關資訊,舉幾個常用的:
getCanonicalName()
:完整的 class 名稱,包含完整 package 路徑getSimpleName()
:class 名稱,不包含 packagegetInterfaces()
:這個 classimplement
的所有 interface,回傳值是Class<?>[]
、可以再進一步取得這些 interface 的資訊getMethods()
:這個 class 裡所有的 method,回傳值是Method[]
、可以透過 Method 物件進一步取得 method 名稱、參數、回傳值等資訊。
所以,我對範例中注入進來的 gameRepo
物件實驗了一下:
// ...result.put("canonicalName", gameRepo.getClass().getCanonicalName());result.put("interfaces", gameRepo.getClass().getInterfaces());// ...
回傳的結果是:
{ "canonicalName": "jdk.proxy6.$Proxy134", "interfaces": [ "chuan13.playground.repository.GameRepo", "org.springframework.data.repository.Repository", "org.springframework.transaction.interceptor.TransactionalProxy", "org.springframework.aop.framework.Advised", "org.springframework.core.DecoratingProxy" ]}
嗯,的確是個 proxy,implement 了我自己寫的 GameRepo
這個 interface、還有許多其他的…… interface 們。
要學的還很多呢 www
延伸閱讀
參考資料
- ChatGPT
- 以上「延伸閱讀」資料