成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么我棄用了Spring的@Autowired

開發 架構
任何架構決策都是利弊權衡的藝術。本文倡導的顯式依賴管理并非要全盤否定Spring的IoC機制,而是希望在框架便利性與系統健壯性之間尋找最佳平衡點。

大家好,我是Jensen。

在Spring框架統治Java企業級開發的黃金時代,類似@Autowired注解的自動注入機制,猶如一把金鑰匙,為開發者打開了依賴注入的魔法之門。通過簡單的注解聲明,Spring容器就能自動將所需的Bean注入到目標位置,這種"聲明即所得"的編程范式極大提升了開發效率。

但在實際項目中,這種便利性正逐漸顯露出其危險的一面。

典型問題案例:在一個訂單處理模塊中,領域對象Order直接通過@Autowired注入支付服務PaymentService。

這種看似優雅的寫法,實則讓領域模型與Spring框架產生了深度耦合,導致以下問題:

// 貧血模型的典型實現
public class Order {
    @Autowired
    private PaymentService paymentService; // 違反單一職責原則
    
    public void pay() {
        paymentService.process(this);
    }
}

一、自動注入“四宗罪”

1. 依賴關系黑盒化

自動注入使得類的依賴項變得隱式且不可見,違背了"顯式優于隱式"的設計原則。當開發者需要理解一個類的完整行為時,不得不借助IDE的輔助功能才能發現所有隱藏依賴。

2. 單元測試困境

在測試領域對象時,Mock依賴項變得異常困難。測試用例必須通過SpringTestContext框架啟動完整容器,導致單元測試退化為集成測試,執行效率呈指數級下降。

3. 循環依賴溫床

當兩個服務通過@Autowired相互注入時,Spring容器會通過三級緩存機制解決循環依賴。這種設計漏洞被框架容忍后,最終導致系統出現"麻花式耦合"的架構問題。

4. 破壞充血模型

在DDD實踐中,領域模型本應是純凈的POJO,自動注入機制迫使領域對象必須知曉Spring容器的存在,導致技術實現細節污染業務核心邏輯。

二、破局之道:顯式依賴管理

我們通過自定義SpringContext工具類實現依賴的顯式獲取,該工具類的核心實現如下:

@Primary
publicclass SpringContext implements ApplicationContextAware, PriorityOrdered, ApplicationRunner {
    privatestatic ApplicationContext applicationContext;
    // 初始化完成的信號
    privatestaticfinal CountDownLatch INITIALIZATION_LATCH = new CountDownLatch(1);

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 通知等待的線程初始化已完成
        INITIALIZATION_LATCH.countDown();
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContext.applicationContext = applicationContext;
    }

    publicstatic <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    // 獲取Bean,需等待應用完全啟動
    publicstatic <T> T getBeanSync(Class<T> clazz) {
        try {
            // 阻塞等待初始化完成,最多等待 1 分鐘
            if (!INITIALIZATION_LATCH.await(1, TimeUnit.MINUTES)) {
                thrownew IllegalStateException("應用初始化超時");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            thrownew RuntimeException("獲取Bean時線程被中斷", e);
        }
        return applicationContext.getBean(clazz);
    }

    @Override
    public int getOrder() {
        return PriorityOrdered.HIGHEST_PRECEDENCE;
    }

}
在訂單領域模型中,我們通過顯式獲取的方式維護領域模型的純粹性:
public class Order {
    private Long orderId;
    private BigDecimal amount;
    private OrderStatus status;

    // 保持領域模型的純潔性
    public void pay() {
        PaymentService paymentService = SpringContext.getBean(PaymentService.class);
        PaymentResult result = paymentService.execute(this);
        
        if (result.isSuccess()) {
            this.status = OrderStatus.PAID;
            DomainEventPublisher.publish(new OrderPaidEvent(this));
        }
    }
}

優勢對比表

維度

自動注入方案

顯式獲取方案

領域模型純凈度

依賴容器

完全POJO

可測試性

需要Spring環境

普通Mock即可

依賴可見性

隱式

顯式

循環依賴風險

代碼可讀性

需要IDE輔助

一目了然

三、最佳實踐指南

分層管理策略

  • 基礎設施層:允許使用@Autowired注入技術組件(如JPA Repository)
  • 領域層:嚴格禁止容器依賴,通過SpringContext獲取必要服務
  • 應用層:有限制地使用構造函數注入

異步環境適配在響應式編程場景下,通過組合模式封裝異步獲取邏輯:

public class AsyncBeanAccessor {
    public static <T> Mono<T> getBeanReactive(Class<T> beanClass) {
        return Mono.fromCallable(() -> SpringContext.getBean(beanClass)).subscribeOn(Schedulers.boundedElastic());
    }
}
  • 測試支持方案通過自定義Mock策略實現依賴隔離:
@Test
public void testOrderPayment() {
    // 配置Mock環境
    SpringContextMock.registerMock(PaymentService.class, mockService);
    
    Order order = new Order(/*...*/);
    order.completePayment();
    
    assertThat(order.getStatus()).isEqualTo(PAID);
}

四、架構選擇思考

在微服務架構深度演進的今天,依賴管理策略的選擇實際上反映了團隊對以下核心問題的認知:

  • 技術邊界的把控:框架應該作為基礎設施存在于系統底層,而不是滲透到核心業務邏輯中
  • 復雜性的轉移:顯式依賴將復雜性從運行時轉移到編碼階段,更符合"Fail Fast"原則
  • 演進式設計:保持領域模型的技術中立性,為未來可能的框架遷移預留可能性

后記:任何架構決策都是利弊權衡的藝術。本文倡導的顯式依賴管理并非要全盤否定Spring的IoC機制,而是希望在框架便利性與系統健壯性之間尋找最佳平衡點。

當我們的系統需要長期演進時,這種克制使用框架特性的做法,終將顯現出它的戰略價值。

責任編輯:姜華 來源: 架構師修行錄
相關推薦

2022-03-20 18:29:38

爬蟲反爬蟲代理

2020-08-10 11:20:59

索引MySQL數據庫

2022-08-15 12:31:59

PythonRuby編程語言

2022-09-26 10:26:27

FieldIDEASpring

2022-05-27 08:44:09

springStarter配置

2024-11-29 08:20:22

Autowired場景項目

2021-06-04 05:21:19

KubernetesDocker容器

2024-06-27 13:45:21

2023-09-07 17:06:21

@Autowired報錯原因分析

2020-05-15 08:30:25

前端開發工具

2018-09-10 15:40:46

GitHubQuery前端

2020-08-14 10:40:35

RestTemplatRetrofitJava

2023-07-31 07:45:12

Spring項目Jakarta

2024-08-08 08:50:21

標簽頁portTab

2011-12-26 09:38:24

諾基亞SymbianBelle

2012-04-04 22:07:12

Android

2012-02-28 09:11:51

語言Lua

2020-07-17 14:06:36

Scrum敏捷團隊

2020-08-14 09:11:29

RedisQPS數據庫

2016-06-14 09:48:19

框架
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91网站在线观看视频 | 精品国产91 | 日本黄色影片在线观看 | 福利社午夜影院 | 亚洲精品www久久久 www.蜜桃av | 成人精品一区 | 99视频在线播放 | 国产精品国产自产拍高清 | www.婷婷| 免费在线观看一区二区三区 | 久久久久国产一区二区三区 | 成人av激情 | 欧美不卡一区二区三区 | 国产欧美视频一区二区 | 中文字幕免费中文 | 欧美视频成人 | 精品一区二区三区免费毛片 | 九色在线观看 | 成人免费片 | 亚洲国产精品一区二区www | 亚洲vs天堂 | 91视频国产一区 | 欧美在线a | 国产一级在线 | 黑人中文字幕一区二区三区 | 欧美日韩精品免费 | 一区在线观看视频 | 极品国产视频 | 久久伊人久久 | 亚洲伊人a| 亚洲精品自在在线观看 | 色888www视频在线观看 | 五月婷婷丁香婷婷 | 精品视频在线观看 | 国产精品精品视频 | 午夜小电影 | 欧美成人综合 | 精品日韩一区 | 国产成人网| 亚洲国产成人在线视频 | 一区二区av |