二、Spring裝配Bean

魚換水發表於2020-05-27

內容

  • 宣告bean
  • 構造器注入和Setter方法注入
  • 裝配Bean
  • 控制bean的建立和銷燬

關鍵詞

  • 裝配(wiring)
  • 元件掃描(component scanning)
  • 自動裝配(AutoWiring)

2.1 Spring配置的可選方案

Spring容器負責建立應用程式中的bean並通過DI來協調這些物件之間的關係,而我們就是需要控制Spring要建立哪些Bean並且如何將其裝配在一起。

Spring提供了三種裝配機制:

  1. 在XML中顯式配置
  2. 在Java中進行顯式配置(JavaConfig)
  3. 隱式的bean發現機制和自動裝配

2.2 自動化裝配bean

自動化裝配實現

  1. 元件掃描(component scanning):Spring會自動發現應用上下文中所建立的bean
  2. 自動裝配(autowiring):Spring自動滿足bean之間的依賴。

元件掃描和自動裝配在一起會顯示出強大的威力,並將顯式配置降低到最少。

// java介面
package Book;

public interface PutBook {
	void put();
}
// Java介面實現類
package Book;
import org.springframework.stereotype.Component;

@Component
public class SetBook implements PutBook {
	private String book_name = "Harry Potter";
	private String author = "JK";
	public void put() {
		System.out.println("book_name"+book_name+"author:"+author);
	}
}

注意第二段程式碼使用了@Component,這個註解將該類作為了元件類,並告知Spring為該類建立一個bean。但是該元件掃描預設不啟用,需要顯式配置Spring,從而命令它去尋找帶有@Component的註解的類,併為其建立bean。

// 啟用元件掃描類
package Book;

import org.springframework.context.annotation.componentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class bookConfig {

}

ComponentScan預設會掃描魚配置類相同的包,從而發現帶有Component註解的類,並在Spring中自動為其建立一個bean

// 測試程式碼
package com.baidu.hankanvideo.book;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.ContextConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BookConfig.class)
public class BookTest {

    @Autowired
    private PutBook putBook;

    @Test
    public void bookIsNotBeNull() {
        assertNotNull(putBook);
    }
}

以上為單元測試程式碼,通過檢查PutBook屬性是否為null,不為null則證明可以發現並注入。

2.2.1 為元件掃描的bean命名

Spring應用上下文中所有的bean都會給定一個ID。如果不指定則會根據類名來指定一個ID。

@Component("lonelyHearts")
public class SetBook implements PutBook {

}

2.2.2 設定元件掃描的基礎包

目前ComponentScan掃描包的範圍會以配置類所在的包作為基礎包(base package)進行掃描,所以指定包和多個包的配置如下。

// 一、單個包
@Configuration
@ComponentScan("model")
或者
@ComponentScan(basePackages="model")

// 二、多個包
@Configuration
@ComponentScan(basePackages={"model","service"})

// 以上方法簡單但是不夠安全,如果包重構或者類被放到其他包,就會出現問題。所以指定類或者介面
@Configuration
@ComponentScan(basePackageClasses={Book.class,PutBook.class})

2.2.3 通過為bean新增註解實現自動裝配

自動裝配就是讓Spring自動滿足bean依賴的一種方法,在滿足依賴的過程中描繪在Spring應用上下文中尋找匹配某個bean需求的其他bean。為了宣告要進行的自動裝配,在Spring中使用@AutoWired。

// Java介面實現類
package Book;
import org.springframework.stereotype.Component;

@Component
public class SetBook implements PutBook {
	private String book_name = "Harry Potter";
	private String author = "JK";

	@AutoWired
	public BookStore(PutBook putBook) {
		this.book = putBook;
	}

	public void put() {
		System.out.println("book_name"+book_name+"author:"+author);
	}
}

總結:

  • @AutoWired可以用在構造器上
  • @AutoWired可以用在屬性的Setter方法上
  • 還可以用在類的任何方法上

2.3 通過Java程式碼裝配bean(顯式裝配)

將第三方庫中的元件裝配到應用中,就需要使用顯式配置的方式,而上面通過元件掃描和自動裝配的自動化配置是不可用的。

JavaConfig是配置程式碼,意味著它不應該包含任何業務邏輯,JavaConfig也不應該侵入到業務邏輯程式碼中。因此常常會將JavaConfig放到單獨的包中,使其與其他的應用程式邏輯分離開來。

2.3.1 建立配置類

// 啟用元件掃描類
package Book;

import org.springframework.context.annotation.Configuration;

@Configuration
public class bookConfig {

}

單單隻有@Configuration註解,但是缺少了上面的ComponentScan註解就會失效。
那麼顯式配置怎麼做呢?

2.3.2 宣告簡單的bean

// 啟用元件掃描類
package Book;

import org.springframework.context.annotation.Configuration;

@Configuration
public class bookConfig {

	// 新增一個方法註冊一個Bean
	@Bean
	public CompactDisc sgtPeppers() {
		return new SgtPeppers();
	}

}

@Bean 註解會告訴Spring這個方法將返回一個物件,該物件要註冊為Spring應用上下文中的bean。方法體中包含最終產生bean例項的邏輯。

2.3.3 藉助JavaConfig實現注入

package soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CDPlayerConfig {
  
  @Bean
  public CompactDisc compactDisc() {
    return new SgtPeppers();
  }
  
  @Bean
  public CDPlayer cdPlayer(CompactDisc compactDisc) {
    return new CDPlayer(compactDisc);
  }

}

cdPlayer()方法請求一個CompactDisc作為引數。當Spring呼叫cdPlayer()建立CDPlayerbean的時候,它會自動裝配一個CompactDisc到配置方法中。然後方法體就可以按照合適的方式使用它。這種方法可以不需引用CompactDisc的@Bean的方法。

2.4 總結

Spring框架的核心是Spring容器,容器負責管理應用中元件的生命週期,它會建立這些元件並保證他們的依賴能夠得到滿足,保證元件完成預定的任務。

相關文章