您好,登錄后才能下訂單哦!
本篇文章和大家了解一下Spring延遲初始化會遇到什么問題。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有所幫助。
首先,讓我們回顧一下 Spring 延遲初始化的概念。在 Spring 中,延遲初始化指的是將 Bean 的實例化推遲到第一次被使用時,而不是在應(yīng)用程序啟動時就立即創(chuàng)建所有的 Bean。這種延遲加載的機制可以提高應(yīng)用程序的性能和資源利用率。
代碼演示:
@Lazy @Component public class MyBean { public MyBean() { System.out.println("My bean init success."); } }
1、 使用構(gòu)造函數(shù)注入
@Service public class MyService { private MyBean myBean; public MyService(MyBean myBean) { this.myBean = myBean; } public void exec() { System.out.println("exec suc"); } }
2、 @Resource 注入
@Service public class MyService { @Resource private MyBean myBean; public void exec() { System.out.println("exec suc"); } }
3、 @Autowired 注入
@Service public class MyService { private MyBean myBean; @Autowired public void setMyBean(MyBean myBean) { this.myBean = myBean; } public void exec() { myBean.exec(); } }
測試結(jié)果
這個非常好理解,myService 并沒有配置@Lazy
,所以在啟動的時候會被初始化。由于 myService 依賴 myBean,myBean 就會被注入。所以這意味著 myBean 要能正常被注入,就得被初始化,如果不初始化就會啟動失敗。這也就是造成 myBean 延遲初始化失效的原因。
解決方法很簡單,在依賴到的地方都配置上@Lazy
,避免出現(xiàn)被非延遲初始化的 Bean 注入了。
@Lazy 注解只對單例(Singleton)作用域的 Bean 有效。默認情況下,Spring 的 Bean 作用域是單例,如果將 Bean 的作用域設(shè)置為其他作用域(如原型、請求、會話等)的是不起作用的。
代碼演示:
默認不做任何配置。
@Component public class MyBean { public MyBean() { System.out.println("My bean init success."); } public void exec() { System.out.println("exec suc"); } }
啟動結(jié)果:
通過觀察啟動結(jié)果,可以看到 myBean 在啟動的時候被初始化了。
加上@Lazy
@Lazy @Component public class MyBean { public MyBean() { System.out.println("My bean init success."); } public void exec() { System.out.println("exec suc"); } }
啟動結(jié)果:
通過觀察啟動結(jié)果,可以看到 myBean 并沒有初始化,說明@Lazy
生效了。
設(shè)置 scope
@Lazy @Component @Scope("prototype") public class MyBean { public MyBean() { System.out.println("My bean init success."); } public void exec() { System.out.println("exec suc"); } }
啟動結(jié)果:
這個時候你會發(fā)現(xiàn),貌似這個結(jié)果不對呀。上面提到,@Lazy 注解只對單例(Singleton)作用域的 Bean 有效。但是我已經(jīng)將 Scope 改為 prototype。 按理來應(yīng)該是這樣:
控制臺會輸出My bean init success.
,然而事實就是沒有。那么這是為什么呢?
由于是增加了@Scope("prototype")
,發(fā)現(xiàn)結(jié)果不符合預(yù)期,那我們就從它入手。我們先回顧一下 Spring Bean 的作用域相關(guān)的知識。當(dāng) Spring Bean 作用域為 prototype
時,每次獲取 Bean 時都會重新創(chuàng)建一個實例。
換句話說,也就意味著,當(dāng)?shù)?Bean 作用域為 prototype 時,Bean 在被使用的才會被初始化,并且每個 Bean 都是全新的。
誒,在使用的時候被初始化,這不就是延遲初始化嗎。改下代碼測試一下:
去掉@Lazy
:
@Component @Scope("prototype") public class MyBean { public MyBean() { System.out.println("My bean init success."); } public void exec() { System.out.println("exec suc"); } }
啟動結(jié)果:
發(fā)現(xiàn)和單獨配置@Lazy
的效果是一樣,并沒有被初始化。
當(dāng) bean 作用域是 prototype 時,這些 bean 每次在需要時,都會按需實例化和初始化,因此它們本質(zhì)上是延遲始化的。所以給他們配置@Lazy
是沒有意義的。
在上面的案例,出現(xiàn)這樣的情況是因為,在啟動的時候 myBean 并沒有,被其他 Bean 依賴和使用。所以表現(xiàn)出和@Lazy
一樣的效果。誤以為當(dāng) Bean 作用域是 prototype 時,@Lazy
可以生效。
由于 spring bean 的默認作用域是:singleton。所以在啟動的時候 bean 會被初始化,如果被標(biāo)記了@Lazy
,會延遲初始化,但是如果被非懶加載的 Bean 注入了,@Lazy
會失效。并且@Lazy
注解只對單例 singleton 作用域的 Bean 有效。
以上就是Spring延遲初始化會遇到什么問題的簡略介紹,當(dāng)然詳細使用上面的不同還得要大家自己使用過才領(lǐng)會。如果想了解更多,歡迎關(guān)注億速云行業(yè)資訊頻道哦!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。