最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring @Lazy注解的定義及詳細(xì)源碼展示

 更新時(shí)間:2025年09月02日 11:44:04   作者:csdn_tom_168  
@Lazy是Spring延遲初始化Bean的注解,通過(guò)推遲實(shí)例化時(shí)機(jī)減少啟動(dòng)時(shí)間與內(nèi)存占用,適用于高成本Bean、條件化延遲及解決循環(huán)依賴,但需注意首次使用性能開(kāi)銷與依賴順序問(wèn)題,本文給大家介紹Spring @Lazy注解的定義及詳細(xì)源碼展示,感興趣的朋友一起看看吧

@Lazy 是 Spring 框架中用于延遲初始化 Bean的核心注解,其核心作用是將 Bean 的實(shí)例化時(shí)機(jī)從“容器啟動(dòng)時(shí)”推遲到“首次被使用時(shí)”,從而減少應(yīng)用啟動(dòng)時(shí)間、降低內(nèi)存占用,尤其適用于初始化成本高或非立即使用的 Bean。以下從注解定義、源碼解析、核心功能、使用場(chǎng)景注意事項(xiàng)展開(kāi)詳細(xì)說(shuō)明。

一、@Lazy注解的定義與源碼解析

@Lazy 位于 org.springframework.context.annotation 包中,其源碼定義如下(簡(jiǎn)化版):

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {
    /**
     * 是否延遲初始化(默認(rèn) true,即延遲;false 表示立即初始化)
     */
    boolean value() default true;
    /**
     * 條件判斷(可選,滿足條件時(shí)才延遲初始化)
     */
    String condition() default "";
}

關(guān)鍵屬性說(shuō)明

  • value:布爾值,控制是否啟用延遲初始化(默認(rèn) true)。
  • condition:SpEL 表達(dá)式(可選),僅當(dāng)表達(dá)式結(jié)果為 true 時(shí),才啟用延遲初始化(用于條件化延遲)。

二、核心功能:延遲初始化的實(shí)現(xiàn)機(jī)制

1.默認(rèn)行為:立即初始化

Spring 容器默認(rèn)在啟動(dòng)時(shí)初始化所有單例 Bean(singleton 作用域),無(wú)論是否被使用。這可能導(dǎo)致:

  • 啟動(dòng)時(shí)間過(guò)長(zhǎng)(尤其是初始化成本高的 Bean)。
  • 內(nèi)存浪費(fèi)(未使用的 Bean 占用資源)。

2.@Lazy的延遲初始化邏輯

當(dāng) Bean 被 @Lazy 標(biāo)記后,Spring 會(huì):

  1. 不立即創(chuàng)建實(shí)例:容器啟動(dòng)時(shí)不初始化該 Bean,僅記錄其延遲初始化的配置。
  2. 首次使用時(shí)創(chuàng)建:當(dāng)?shù)谝淮瓮ㄟ^(guò) @Autowired、getBean() 等方式獲取該 Bean 時(shí),才觸發(fā)實(shí)例化。

3.與作用域的協(xié)同

@Lazy 對(duì)不同作用域的 Bean 影響不同:

作用域默認(rèn)初始化時(shí)機(jī)@Lazy 效果
singleton(單例)容器啟動(dòng)時(shí)初始化延遲到首次使用時(shí)初始化(全局僅一次)。
prototype(原型)每次 getBean() 時(shí)初始化無(wú)變化(原型 Bean 本就每次新建,@Lazy 不影響)。
request/session(Web 作用域)作用域創(chuàng)建時(shí)初始化延遲到作用域首次使用時(shí)初始化(如 HTTP 請(qǐng)求首次訪問(wèn)時(shí))。

三、典型使用場(chǎng)景與示例

1.高初始化成本的 Bean

例如,數(shù)據(jù)庫(kù)連接池(如 HikariCP)、緩存客戶端(如 RedisTemplate)等,初始化時(shí)需要加載大量配置或建立長(zhǎng)連接,延遲初始化可顯著減少啟動(dòng)時(shí)間。

示例

@Service
@Lazy // 延遲初始化(首次使用時(shí)創(chuàng)建)
public class RedisClient {
    private final RedisTemplate<String, Object> redisTemplate;
    // 構(gòu)造器初始化成本高(連接 Redis 服務(wù)器)
    public RedisClient(RedisConnectionFactory connectionFactory) {
        this.redisTemplate = new RedisTemplate<>();
        this.redisTemplate.setConnectionFactory(connectionFactory);
        this.redisTemplate.afterPropertiesSet(); // 觸發(fā)連接
    }
    public void setValue(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }
}

效果:應(yīng)用啟動(dòng)時(shí),RedisClient 不會(huì)立即連接 Redis,而是在第一次調(diào)用 setValue 時(shí)才初始化。

2.條件化延遲加載

結(jié)合 condition 屬性,僅當(dāng)滿足特定條件時(shí)才延遲初始化(如根據(jù)環(huán)境變量或配置屬性)。

示例

@Service
@Lazy(condition = "#{environment.getProperty('feature.analytics.enabled') == 'true'}") // 僅當(dāng) analytics 功能啟用時(shí)延遲初始化
public class AnalyticsService {
    // 初始化成本高(連接分析服務(wù))
    public AnalyticsService(AnalyticsClient client) {
        // ...
    }
}

效果:若 application.propertiesfeature.analytics.enabled=false,則 AnalyticsService 會(huì)被立即初始化(即使未使用);若為 true,則延遲到首次使用時(shí)初始化。

3.避免循環(huán)依賴

在循環(huán)依賴場(chǎng)景中,@Lazy 可打破“構(gòu)造器注入導(dǎo)致的循環(huán)依賴死鎖”。例如,A 依賴 B,B 依賴 A,若兩者均使用構(gòu)造器注入,Spring 無(wú)法解決循環(huán)依賴;但通過(guò) @Lazy 延遲其中一個(gè)的初始化,可避免啟動(dòng)時(shí)報(bào)錯(cuò)。

示例

@Service
public class A {
    private final B b;
    // 構(gòu)造器注入 B(但 B 被 @Lazy 標(biāo)記)
    @Autowired
    public A(@Lazy B b) {
        this.b = b;
    }
}
@Service
@Lazy // B 延遲初始化
public class B {
    private final A a;
    // 構(gòu)造器注入 A(A 已初始化,無(wú)循環(huán)依賴)
    @Autowired
    public B(A a) {
        this.a = a;
    }
}

效果:A 初始化時(shí),B 被標(biāo)記為延遲,因此不會(huì)立即觸發(fā) B 的構(gòu)造器(避免循環(huán)依賴)。當(dāng)首次使用 B 時(shí),A 已存在,可正常初始化。

四、源碼實(shí)現(xiàn)細(xì)節(jié)與關(guān)鍵類

1.LazyAnnotationBeanPostProcessor

Spring 處理 @Lazy 的核心類,繼承自 InstantiationAwareBeanPostProcessorAdapter,負(fù)責(zé)將 @Lazy 標(biāo)記的 Bean 轉(zhuǎn)換為“延遲初始化”的代理對(duì)象。其關(guān)鍵邏輯如下:

(1)掃描@Lazy注解

在解析 @Bean 方法或 @Component 類時(shí),ConfigurationClassParser 會(huì)掃描 @Lazy 注解,獲取其 valuecondition 屬性。

(2)生成代理對(duì)象

@Lazy 啟用(value=truecondition 滿足),LazyAnnotationBeanPostProcessor 會(huì)為該 Bean 生成一個(gè)延遲初始化代理(通常是 CGLIB 或 JDK 動(dòng)態(tài)代理)。該代理在首次調(diào)用方法時(shí),才會(huì)觸發(fā)實(shí)際的 Bean 實(shí)例化。

(3)條件判斷

@Lazycondition 屬性存在,LazyAnnotationBeanPostProcessor 會(huì)通過(guò) ExpressionEvaluator 解析 SpEL 表達(dá)式,判斷是否啟用延遲初始化。

2.BeanDefinition的lazyInit屬性

Spring 的 BeanDefinition 接口有一個(gè) isLazyInit() 方法,用于標(biāo)記該 Bean 是否延遲初始化。LazyAnnotationBeanPostProcessor 會(huì)根據(jù) @Lazy 的配置設(shè)置該屬性為 true,從而告知 Spring 容器延遲初始化該 Bean。

五、注意事項(xiàng)與常見(jiàn)問(wèn)題

1.首次使用的性能開(kāi)銷

延遲初始化的 Bean 在首次使用時(shí)會(huì)觸發(fā)實(shí)例化,可能導(dǎo)致短暫的延遲(如連接數(shù)據(jù)庫(kù)、加載配置)。需權(quán)衡啟動(dòng)時(shí)間與首次使用時(shí)間的總和。

2.與@PostConstruct的順序

若 Bean 同時(shí)被 @Lazy@PostConstruct 標(biāo)記,@PostConstruct 方法會(huì)在 Bean 實(shí)例化后(首次使用時(shí))執(zhí)行,而非容器啟動(dòng)時(shí)。

3.循環(huán)依賴的限制

@Lazy 可打破構(gòu)造器注入的循環(huán)依賴,但無(wú)法解決所有循環(huán)依賴場(chǎng)景(如字段注入的循環(huán)依賴仍需通過(guò) @Lazy 或重構(gòu)代碼解決)。

4.與@Conditional的協(xié)同

@Lazy 可與 @Conditional 注解(如 @ConditionalOnProperty)結(jié)合使用,實(shí)現(xiàn)更靈活的條件化延遲初始化。例如:僅當(dāng)某個(gè)屬性為 true 時(shí),才延遲初始化。

5.原型作用域的@Lazy

prototype 作用域的 Bean 本身每次 getBean() 時(shí)都會(huì)創(chuàng)建新實(shí)例,@Lazy 對(duì)其無(wú)影響(因?yàn)?prototype 本就延遲初始化)。

6.全局懶加載配置

Spring Boot 支持全局懶加載(通過(guò) spring.main.lazy-initialization=true),此時(shí)所有單例 Bean 默認(rèn)延遲初始化(除非顯式標(biāo)記 @Lazy(false))。@Lazy 可覆蓋全局配置。

六、總結(jié)

@Lazy 是 Spring 中優(yōu)化啟動(dòng)時(shí)間和資源占用的核心注解,通過(guò)延遲初始化非立即使用的 Bean,顯著提升應(yīng)用性能。其核心機(jī)制依賴 LazyAnnotationBeanPostProcessorBeanDefinitionlazyInit 屬性,支持條件化延遲和與多種注解的協(xié)同。理解其源碼和使用場(chǎng)景,有助于開(kāi)發(fā)者編寫更高效、可維護(hù)的 Spring 應(yīng)用。

到此這篇關(guān)于Spring @Lazy 詳解及詳細(xì)源碼展示的文章就介紹到這了,更多相關(guān)Spring @Lazy內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?Security登錄表單配置示例詳解

    Spring?Security登錄表單配置示例詳解

    這篇文章主要介紹了Spring?Security登錄表單配置,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • 使用Filter實(shí)現(xiàn)登錄權(quán)限驗(yàn)證

    使用Filter實(shí)現(xiàn)登錄權(quán)限驗(yàn)證

    這篇文章主要為大家詳細(xì)介紹了使用Filter實(shí)現(xiàn)登錄權(quán)限驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • JavaWeb開(kāi)發(fā)之使用jQuery與Ajax實(shí)現(xiàn)動(dòng)態(tài)聯(lián)級(jí)菜單效果

    JavaWeb開(kāi)發(fā)之使用jQuery與Ajax實(shí)現(xiàn)動(dòng)態(tài)聯(lián)級(jí)菜單效果

    這篇文章主要介紹了JavaWeb開(kāi)發(fā)之使用jQuery與Ajax實(shí)現(xiàn)動(dòng)態(tài)聯(lián)級(jí)菜單效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-10-10
  • JAVA字符串拼接常見(jiàn)方法匯總

    JAVA字符串拼接常見(jiàn)方法匯總

    這篇文章主要介紹了JAVA字符串拼接常見(jiàn)方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • java 實(shí)現(xiàn)切割文件和合并文件的功能

    java 實(shí)現(xiàn)切割文件和合并文件的功能

    這篇文章主要介紹了java 實(shí)現(xiàn)切割文件和合并文件的功能的相關(guān)資料,這里實(shí)現(xiàn)文件的切割的實(shí)現(xiàn)代碼和文件合并的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2017-07-07
  • springboot 多環(huán)境切換的方法

    springboot 多環(huán)境切換的方法

    這篇文章主要介紹了springboot 多環(huán)境切換的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • @SpringBootTest 注解報(bào)紅問(wèn)題及解決

    @SpringBootTest 注解報(bào)紅問(wèn)題及解決

    這篇文章主要介紹了@SpringBootTest 注解報(bào)紅問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java實(shí)現(xiàn)學(xué)生信息錄入界面

    java實(shí)現(xiàn)學(xué)生信息錄入界面

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)學(xué)生信息錄入界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 新手了解java 泛型基礎(chǔ)知識(shí)

    新手了解java 泛型基礎(chǔ)知識(shí)

    這篇文章主要給大家介紹了關(guān)于Java中泛型使用的簡(jiǎn)單方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • Mybatis中如何設(shè)置sqlSession自動(dòng)提交

    Mybatis中如何設(shè)置sqlSession自動(dòng)提交

    在MyBatis中,默認(rèn)情況下,獲取的SqlSession對(duì)象不會(huì)自動(dòng)提交事務(wù),這意味著在進(jìn)行更新、刪除或插入等操作后,需要顯式調(diào)用commit方法來(lái)提交事務(wù),但是,可以在獲取SqlSession時(shí)通過(guò)將openSession方法的參數(shù)設(shè)置為true
    2024-09-09

最新評(píng)論

广饶县| 克拉玛依市| 阳西县| 内江市| 仪陇县| 独山县| 清原| 肇源县| 增城市| 克拉玛依市| 梧州市| 体育| 聊城市| 宣威市| 洛浦县| 龙岩市| 留坝县| 漳浦县| 南郑县| 水富县| 额敏县| 芦溪县| 涪陵区| 建始县| 友谊县| 泾阳县| 英德市| 曲阜市| 磴口县| 隆安县| 廊坊市| 改则县| 亳州市| 临桂县| 石狮市| 长沙市| 忻城县| 珠海市| 中山市| 海宁市| 夹江县|