內容
- 宣告bean
- 構造器注入和Setter方法注入
- 裝配Bean
- 控制bean的建立和銷燬
關鍵詞
- 裝配(wiring)
- 元件掃描(component scanning)
- 自動裝配(AutoWiring)
2.1 Spring配置的可選方案
Spring容器負責建立應用程式中的bean並通過DI來協調這些物件之間的關係,而我們就是需要控制Spring要建立哪些Bean並且如何將其裝配在一起。
Spring提供了三種裝配機制:
- 在XML中顯式配置
- 在Java中進行顯式配置(JavaConfig)
- 隱式的bean發現機制和自動裝配
2.2 自動化裝配bean
自動化裝配實現
- 元件掃描(component scanning):Spring會自動發現應用上下文中所建立的bean
- 自動裝配(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容器,容器負責管理應用中元件的生命週期,它會建立這些元件並保證他們的依賴能夠得到滿足,保證元件完成預定的任務。