iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0

依賴注入 (Dependency Injection) 與控制反轉 (Inversion Of Control)

控制反轉

當我們想要談一場轟轟烈烈的戀愛時,由我們主動出擊尋找生命中的她/他。
例如我喜歡金髮碧眼翹臀女孩,或者我喜歡狂野大胸肌男孩。

此時,誰依賴誰:我依賴於金髮碧眼翹臀女孩 or 我依賴於狂野大胸肌男孩。
我要主動找他,我還要跟他安排見面,什麼事情都只能自己來,我和金髮碧眼翹臀女孩 or 我和狂野大胸肌男孩產生了高度耦合。

這樣實在太累了,於是我們找到了婚友社......
https://ithelp.ithome.com.tw/upload/images/20230916/201150363XXQOI0X9V.png
告訴婚友社我們的理想對象,金髮/碧眼/翹臀 or 狂野/大胸肌。
專業顧問可能會白眼你,但他還是會盡責地幫你達成你的願望(應該吧)。
我們只要耐心的等待顧問幫我們安排見面,然後專心的戀愛就可以了!

此時,誰依賴誰:我依賴於婚友社。
我們將控制權(生殺大權QQ)交給了婚友社,降低了耦合度。

依賴注入

那我們要如何實現控制反轉,則是依靠依賴注入。
依賴注入意味著為物件提供其實例變數。
用上述的例子此處的物件為我們,嗯好吧,只有我。
實例變數則是婚友社幫我找的金髮碧眼翹臀女孩,或者狂野大胸肌男孩。

Spring IoC 容器

org.springframework.beansorg.springframework.context 套件是 Spring Framework 的 IoC 容器的基礎。
在 Spring 中,構成應用程式主幹並由 Spring IoC 容器管理的物件稱為 Bean。
Bean 以及它們之間的依賴關係定義在 Configuration metadata
Spring IoC 容器透過 Configuration metadata 如何實例化、配置和組裝應用程式中的物件。
由你來告訴 Spring 容器你的理想對象要如何,控制權反轉至 Spring 容器。

Spring IoC 容器的職責

  • 實例化 Bean
  • 配置 Bean 及其屬性以進行依賴注入,並將其附加到其相應的對象
  • 管理 Bean 的整個生命週期

https://ithelp.ithome.com.tw/upload/images/20230916/20115036BRnlY3LFzc.png

Spring Framework 提供兩種不同類型的容器

  1. BeanFactory:最簡單的容器,提供基本的 DI
  2. ApplicationContext:ApplicationContext 包括了 BeanFactory 所有的功能,整合了 Spring 的 AOP 功能。

下表列出了 BeanFactory 和 ApplicationContext 介面和其實作所提供的功能。

Feature BeanFactory ApplicationContext
Bean instantiation/wiring Yes Yes
自動註冊 BeanPostProcessor  No Yes
自動註冊 BeanFactoryPostProcessor  No Yes
方便的 MessageSource 訊息處理 (i18n 多語系) No Yes
ApplicationEvent 發佈 No Yes

Configuration metadata

我們有三種方式可以提供給 Spring IoC 容器 Configuration metadata:

  1. XML-based configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  <bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
  </bean>

  <bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
  </bean>

  <!-- more bean definitions go here -->

</beans>
// create and configure beans
ApplicationContext context =
    new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});

// retrieve configured instance
PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class);

// use configured instance
List userList service.getUsernameList();
  1. Annotation-based configuration
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context = "http://www.springframework.org/schema/context"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   <!-- bean definitions go here -->

</beans>

配置完畢後,就可以使用以下 Annotation 。

  • @Required
  • @Autowired
  • @Qualifier
  • @Primary
  • @Resource
  • @PostConstruct, @PreDestroy  (JSR-250 annotations)
  • @Inject, @Qualifier, @Named, @Provider (JSR330 annotations)
  1. Java-based configuration
  • 基本概念的 @Configuration 和 @Bean:
    @Bean 的 Annotation 用於表達說 Spring IoC 容器管理的對象定義實例化、配置和初始化邏輯。
    @Configuration 的 Annotation 則是表明該類別可以被 Spring IoC 容器做 bean 定義的來源。
@Configuration
public class AppConfig {
  @Bean
  public MyService myService() {
      return new MyServiceImpl();
  }
}

那其實這樣的配置就如同下面的 XML 定義方式是等價的

<beans>
  <bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
  • 使用 AnnotationConfigApplicationContext 實例化 Spring 容器
    它不僅能夠接受 @Configuration 類別作為輸入,還可以接受普通的 @Component 類別以及帶有 JSR-330 元數據標註的類別。

不僅如此,還可以尬在一起組合 Java 與 XML 設定。

  1. XML為主使用 @Configuration 類別
  2. 將 @Configuration 類別聲明為純 Spring 元素
  3. 使用 <context:component-scan/> 來掃描 @Configuration 類別
  4. 以 @Configuration 類別為中心的 XML 使用與 @ImportResource:只需使用 @ImportResource,並定義所需的XML 即可

下一篇
第 2 日 Spring IoC 容器 Configuration metadata 實作~XML-based configuration
系列文
大內高手也有春天嗎~Spring Boot 三十天純愛手扎2
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言