慢慢來比較快诀姚,虛心學(xué)技術(shù)
前言:創(chuàng)建應(yīng)用對象之間協(xié)作關(guān)系的行為通常稱為裝配( wiring )响牛,這也是依賴注入( DI )的本質(zhì)
Spring提供三種Bean裝配機(jī)制:
- 在 XML 中進(jìn)行顯式配置。
- 在 Java 中進(jìn)行顯式配置
- 隱式的 bean 發(fā)現(xiàn)機(jī)制和自動裝配
一、為什么使用JavaConfig顯式配置呀打?
相比于XML顯式配置矢赁,javaConfig顯然是更好的方案
- Ⅰ.本就是java代碼,便于重構(gòu)管理
- Ⅱ.類型安全贬丛,更為強(qiáng)大
- Ⅲ.配置方便撩银,簡潔
二、怎么配置瘫寝?
java顯式配置:類似于XML配置模式蜒蕾,顯式配置每個Bean的名稱
在實(shí)現(xiàn)之前我們需要了解一下幾個基本注解:
@Autowired :標(biāo)記于屬性,方法等焕阿,自動裝配的關(guān)鍵注解咪啡,依賴注入的表現(xiàn),該注解可以自動尋找并從Spring容器中提取使用該注解的bean并注入到對應(yīng)的屬性中去
@Bean:該注解用于配置類中暮屡,注明某方法是裝配方法撤摸,方法名就是裝配的Bean名稱(javaConfig顯式配置的核心注解)
@Configuration :標(biāo)記于配置類,標(biāo)明當(dāng)前類是一個配置類
① 與上一篇文章一樣褒纲,基礎(chǔ)類代碼不變准夷。
public class CDBean {
/**
* 定義CD名
*/
private String title="The World!";
/**
* 定義CD作者
*/
private String author="Mr.D";
}
② CDPlayerImp類增加CDPlayerImpl(CDBean cdBean)構(gòu)造方法,方便后續(xù)注入
public class CDPlayerImpl implements CDPlayer {
private CDBean cdBean;
public CDPlayerImpl() {
super();
}
public CDPlayerImpl(CDBean cdBean) {
super();
this.cdBean = cdBean;
}
@Override
public void playCD() {
System.out.println("正在播放:"+cdBean.getTitle()+" by "+cdBean.getAuthor());
}
}
③ CDConfig類更改配置方式莺掠,顯式配置每一個類
@Configuration//標(biāo)明配置
public class CDConfig {
@Bean
public CDBean cdBean(){
return new CDBean();
}
@Bean
public CDPlayer cdPlayer(){
return new CDPlayerImpl(cdBean());
}
}
④注解測試衫嵌,將配置類指向CDConfig2
此處使用Spring提供的測試類SpringJUnit4ClassRunner幫助測試,以便在測試開始的時候自動創(chuàng)建 Spring 的應(yīng)用上下文彻秆,而@ContextConfiguration可以指定創(chuàng)建上下文的加載方式以及配置的位置等
@RunWith(SpringJUnit4ClassRunner.class)//使用Spring提供的測試包進(jìn)行測試楔绞,主要幫助實(shí)現(xiàn)bean的裝載環(huán)境
@ContextConfiguration(loader = AnnotationConfigContextLoader.class,classes = {CDConfig2.class})//配置類指向CDConfig2
public class AppTest
{
//使用注解自動注入
@Autowired
private CDPlayer cdPlayer;
/**
* Rigorous Test :-)
*/
@Test
public void play()
{
this.cdPlayer.playCD();
}
}
⑤測試結(jié)果:
正在播放:The World! by Mr.D
⑥Spring提供另一種測試方式,通過Spring應(yīng)用上下文AnnotationConfigApplicationContext上下文實(shí)現(xiàn)進(jìn)行測試
public class App
{
public static void main(String[] args) {
/**
* 之所以要指定配置類唇兑,相當(dāng)于酒朵,寫了xml文件也一樣需要指定xml文件位置一樣,spring并不能自動開啟注解并讀取配置
*/
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(CDConfig2.class);
//獲取應(yīng)用上下文中的所有Bean名稱
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String className : beanDefinitionNames){
System.out.println(className);
}
CDPlayer cdPlayer = applicationContext.getBean(CDPlayer.class);
cdPlayer.playCD();
}
}
⑦ 測試結(jié)果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
CDConfig2
cdBean
cdPlayer
正在播放:The World! by Mr.D
注:
Ⅰ扎附、@Bean注解可以為Bean另起ID蔫耽,源碼中有屬性如下,name屬性是一個用{}包圍起來字符串?dāng)?shù)組留夜,表明可以定義多個id:
public @interface Bean {
/**
* Alias for {@link #name}.
* <p>Intended to be used when no other attributes are needed, for example:
* {@code @Bean("customBeanName")}.
* @since 4.3.3
* @see #name
*/
@AliasFor("name")
String[] value() default {};
/**
* The name of this bean, or if several names, a primary bean name plus aliases.
* <p>If left unspecified, the name of the bean is the name of the annotated method.
* If specified, the method name is ignored.
* <p>The bean name and aliases may also be configured via the {@link #value}
* attribute if no other attributes are declared.
* @see #value
*/
@AliasFor("value")
String[] name() default {};
}
由上述源碼可做如下更改:
@Configuration
public class CDConfig2 {
@Bean(name = {"CDBEAN"})
public CDBean cdBean(){
return new CDBean();
}
@Bean
public CDPlayer cdPlayer(){
return new CDPlayerImpl(cdBean());
}
}
執(zhí)行⑥測試結(jié)果如下:CDBean的裝配ID已成功更改
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
CDConfig2
CDBEAN
cdPlayer
正在播放:The World! by Mr.D
Ⅱ匙铡、@Bean注解的使用,內(nèi)部注入不只是能在構(gòu)造方法內(nèi)碍粥,還可以在setter和普通方法等注入
@Configuration
public class CDConfig2 {
@Bean(name = {"CDBEAN"})
public CDBean cdBean(){
return new CDBean();
}
@Bean
public CDPlayer cdPlayer(){
CDPlayer cdPlayer = new CDPlayerImpl();
cdPlayer.setCDBean(cdBean());//在setter方法中注入
}
}
總結(jié)
1慰枕、JavaConfig顯式配置相對于XML顯式配置來說,具有配置簡單即纲,維護(hù)方便的優(yōu)點(diǎn)
2、JavaConfig顯式配置主要依賴于@Bean注解和@Configuration兩個注解實(shí)現(xiàn)博肋,其中@Configuration注解標(biāo)明當(dāng)前類為配置類低斋,而@Bean使用在配置類中的方法內(nèi)蜂厅,定義一個裝配類名為方法名的Bean
3、Spring使用@Autowired進(jìn)行依賴注入
4膊畴、Spring中我們可以通過兩種方式方便的對javaConfig顯式配置進(jìn)行測試掘猿,一種是結(jié)合SpringJUnit4ClassRunner模擬裝配環(huán)境進(jìn)行測試,一種是使用應(yīng)用上下文AnnotationConfigApplicationContext進(jìn)行測試
參考文檔
【1】《Spring 實(shí)戰(zhàn)(第 4 版)》·Craig Walls