Spring的實例化和依賴注入時機與延遲實例化

原文鏈接:https://blog.csdn.net/xfx_1994/article/details/103873129?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

Spring的實例化

使用@Autowired可以注入一個bean進來

@Autowired
private Diana diana;

那麼如果在容器中沒有Diana的對象被實例化的時候應用程序會報錯嗎?我們可以通過把Diana上面的@Component註釋掉來看一下結果如何

//@Component
public class Diana {
	public void r(){
        System.out.println("Diana R");
    }
}

@RestController
@RequestMapping("/v1/banner")
public class BannerController {
    @Autowired
    private Diana diana;
}

啓動SpringBoot會出現以下結果:
在這裏插入圖片描述

由此可見,如果spring無法在容器中找到Diana的對象,在默認的機制下啓動時就會直接報錯。

當在@Autowired後面加上 (required = false),變成

@RestController
@RequestMapping("/v1/banner")
public class BannerController {

    @Autowired(required = false)
    private Diana diana;
    
	@GetMapping("/test")
    public String test1() {
        diana.r();
        return "Hello test1";
    }
}

SpringBoot可以 正常啓動,但是當訪問diana下面的方法時會出現下面這樣的結果

在這裏插入圖片描述

出現這樣的情況注入是沒有問題的,而是由於容器中沒有diana這個對象卻又調用diana下面的方法

結論:
_如果spring無法在容器中找到Diana的對象,在默認的機制下啓動時就會直接報錯。我們可以通過@Autowired(required = false)的方式令應用程序可以正常啓動。 _

依賴注入時機
IOC容器究竟是在什麼時候實例化對象並把對象注入到代碼片段裏的呢?是當請求訪問Controller的時候才進行實例化並注入,還是在SpringBoot應用啓動時就開始實例化並把對象注入到代碼片段的呢?

由之前的代碼可以看出,當把Diana上面的@Component註釋掉時,SpringBoot應用啓動時應用程序會立即報錯,我們也可以通過在Diana這個類中加一個無參的構造方法來驗證以下
 

@Component
public class Diana {
	public Diana() {
        System.out.println("Hello Diana");
    }
    public void r(){
        System.out.println("Diana R");
    }
}

應用程序啓動時控制檯打印出了"Hello Diana"

在這裏插入圖片描述

結論:
默認機制下,在SpringBoot應用啓動時,IOC容器就開始實例化對象並把對象注入到代碼片段裏

延遲實例化

SpringBoot默認是立即實例化的機制,我們可以通過 @Lazy讓它變成延遲實例化。

@Component
@Lazy
public class Diana {

在這裏插入圖片描述

當只在Diana上加上 @Lazy,啓動應用卻發現Diana仍然是立即實例化,@Lazy並沒有起作用。這是因爲BannerController是立即實例化的,那它下面的屬性如果是@Autowired的就也需要立即實例化,只加在Diana上的 @Lazy是會被忽略掉的。如果真的需要延遲實例化就需要在BannerController也加上@Lazy或者是BannerController注入Diana的地方加上@Lazy,示例代碼如下:
 

@RestController
@RequestMapping("/v1/banner")
@Lazy
public class BannerController {

或者

@Autowired
@Lazy
private Diana diana;

當訪問當前的Controller控制檯打印出了下面的結果:

在這裏插入圖片描述

由此可見,此時是當請求訪問Controller的時候才進行實例化並注入

如果沒有特殊理由最好不要開啓延遲實例化。使用默認機制提前實例化纔是一個比較好的做法,因爲可以儘早發現問題,避免很多問題在運行時才被發現。

原文鏈接:https://blog.csdn.net/xfx_1994/article/details/103873129?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

 

 

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