理解Spring中的IoC和DI

什麼是IoC和DI

IoC(Inversion of Control 控制反轉):是一種面向對象編程中的一種設計原則,用來減低計算機代碼之間的耦合度。其基本思想是:藉助於「第三方」實現具備依賴關係的對象之間的解耦。php

DI(Dependence Injection 依賴注入):將實例變量傳入到一個對象中去(Dependency injection means giving an object its instance variables)。java

  • 控制反轉是一種思想
  • 依賴注入是一種設計模式
  • IoC框架使用依賴注入做爲實現控制反轉的方式

爲何須要

在沒有IoC以前,咱們要在A類中使用B類,就要在A類中newB類的實例,這樣A類和B類之間就出現了耦合。spring

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 註解啓用了組件掃描。this

@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 揭祕

原文首發在個人簡書 www.jianshu.com/p/7f7e089f4…

相關文章
相關標籤/搜索