天天看點

了解Spring中的IoC和DI什麼是IoC和DI為什麼需要Spring 中的IoC總結參考資料

什麼是IoC和DI

IoC(Inversion of Control 控制反轉):是一種面向對象程式設計中的一種設計原則,用來減低計算機代碼之間的耦合度。其基本思想是:借助于“第三方”實作具有依賴關系的對象之間的解耦。

DI(Dependence Injection 依賴注入):将執行個體變量傳入到一個對象中去(Dependency injection means giving an object its instance variables)。

  • 控制反轉是一種思想
  • 依賴注入是一種設計模式
  • IoC架構使用依賴注入作為實作控制反轉的方式

為什麼需要

在沒有IoC之前,我們要在

A

類中使用

B

類,就要在

A

類中

new

B

類的執行個體,這樣

A

類和

B

類之間就出現了耦合。

public class A {
    private B b = new B();
}           

複制

使用了IoC之後,我們就把執行個體化這樣操作交給架構去幫我們做了。

Spring 中的IoC

容器是Spring的核心,Spring容器負責建立應用程式中的bean并通過DI來協調這些對象之間的關系。

Spring容器并不是隻有一個,Spring自帶多個容器的實作,可以歸納為兩種不同的類型:

  1. bean工廠(

    BeanFactory

    ),最簡單的容器,提供基本的DI支援。
  2. 應用上下文(

    ApplicationContext

    ),繼承了

    BeanFactory

    ,并提供應用架構級别的服務。

作為開發人員,我們需要告訴Spring哪些對象要作為bean裝配到容器中,bean和bean之間的依賴關系。Spring提供了三種主要的裝配機制:

  • 隐式的bean發現機制和自動裝配
  • 在Java中進行顯示配置
  • 在XML中進行顯示配置

下面我們逐一介紹這三種機制。

自動裝配bean

元件掃描:spring會自動發現應用上下文中所建立的bean

@Component

注解表明該類會作為元件類,并告知Spring要為這個類建立bean。

@Component
public class Dog {

}           

複制

@ComponentScan

注解啟用了元件掃描。

@Configuration
@ComponentScan
public class DemoApplication {

}           

複制

自動裝配:Spring自動滿足bean之間的依賴

@Autowired

注解可以作用在構造器、方法、屬性上。

@Component
public class Dog {
  	// 屬性
    @Autowired
    private Cat cat;

  	// 構造器
    // 從Spring 4.3開始,具有單個構造函數的類可以省略@Autowired注釋
    @Autowired
    public Dog(Cat cat) {
        this.cat = cat;
    }

  	// 方法
    @Autowired
    public void setCat(Cat cat) {
        this.cat = cat;
    }
}           

複制

在Java中裝配bean

組價配置:聲明一個配置類,并在配置類中配置bean

@Configuration

注解表明這個類是配置類,我們可以在配置類下建立bean。

@bean

注解會告訴Spring這個方法将會傳回一個對象,該對象要注冊為Spring上下文中的bean。

/**
 * 普通類
 */
public class BaseBean {

    public void p() {
        System.out.println("Hello bean");
    }
}



/**
 * 配置類
 */
@Configuration
public class BeanConfig {

  	// 這個方法傳回一個對象,Spring會把這個對象注冊為bean
    @Bean
    public BaseBean getBaseBean() {
        return new BaseBean();
    }

}           

複制

元件注入:在配置類中把被依賴的元件注入另一個元件中

兩種方式注入bean:

  1. 我們可以直接調用

    get

    方法,擷取到對應的元件
  2. get

    方法中把被依賴的元件作為參數傳入,Spring在調用這個方法時,會自動為你注入。
/**
 * 普通類
 */
public class BaseBean {

    public void p() {
        System.out.println("Hello bean");
    }
}

/**
 * 普通類
 */
public class UserBean {
    private BaseBean baseBean;

    public UserBean(BaseBean baseBean) {
        this.baseBean = baseBean;
    }
}



/**
 * 配置類
 */
@Configuration
public class BeanConfig {

    // 這個方法傳回一個對象,Spring會把這個對象注冊為bean
    @Bean
    public BaseBean getBaseBean() {
        return new BaseBean();
    }

    /**
     * 以下為兩種注入bean的方法
     */
  	// 方法一:直接調用get方法
    @Bean
    public UseBean getUseBean() {
        return new UseBean(getBaseBean());
    }

  	// 方法二:當做參數傳入,Spring将自動為你注入
    @Bean
    public UseBean getUseBean(BaseBean baseBean) {
        return new UseBean(baseBean);
    }

}           

複制

通常情況下我們都會使用方法二。

通過XML裝配bean

盡管現在我們已經不再怎麼使用XML裝配bean,但在Spring剛剛出現的時候,XML是描述配置的主要方式,我們還是有必要了解一下的。

在使用JavaConfig的時候,我們建立了一個配置類來裝配bean,而在XML配置中,我們需要建立一個XML檔案,并且要以

<beans>

元素為根。

最為簡單的Spring XML配置如下所示:

<?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.xsd">

    <!-- 在這裡配置你的bean -->

</beans>           

複制

元件配置

以上文的

BaseBean

為例,我們在XML檔案中把它聲明為bean。

<bean id="baseBean" class="com.example.demo.BaseBean" />           

複制

元件注入

<bean id="useBean" class="com.example.demo.UseBean"
      c:_="baseBean" />           

複制

XML的文法我就不再這裡詳述了,有興趣的同學可以自行學習。

總結

本文我們簡單介紹了Spring中的IoC,介紹了Spring中裝配bean的三種方式:自動化配置,基于Java的顯式配置以及基于XML的顯式配置。這些技術都是為了描述Spring應用中的元件以及元件之間的關系。

一般來說我們都會使用自動化配置,盡量避免顯式配置帶來的維護成本。如果不得不使用顯式配置的話,我們優先選擇基于Java的配置,它比基于XML的配置更加強大、類型安全并且易于重構。

參考資料

控制反轉(IoC)與依賴注入(DI)

Spring 實戰

Spring 揭秘