Bean -- 一種表達(dá)實(shí)體和信息的規(guī)范返帕,便于封裝重用。
Bean有以下特點(diǎn):
1、所有屬性為private? ? 2究珊、提供默認(rèn)構(gòu)造方法? ? 3、提供Setter和Getter? ? 4纵苛、實(shí)現(xiàn)Serializable接口
Spring裝配Bean三種方式: XML顯式配置剿涮、Java顯式配置、自動(dòng)裝配攻人。
一取试、自動(dòng)裝配
Spring通過以下兩個(gè)角度來實(shí)現(xiàn)自動(dòng)化裝配
1、組件掃描:Spring會(huì)自動(dòng)發(fā)現(xiàn)應(yīng)用上下文中所創(chuàng)建的bean
2贝椿、自動(dòng)裝配:Spring自動(dòng)滿足bean之間的依賴
接下來以一個(gè)CD播放器的例子來演示自動(dòng)裝配
首先定義媒體播放器和CD兩個(gè)接口
package soundsystem;
public interface MediaPlayer {
void play();
}
package soundsystem;
public interface CompactDisc {
void play();
}
定義CD播放器類實(shí)現(xiàn)媒體播放器接口
package soundsystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer implements MediaPlayer{
private CompactDisccd;
@Autowired
? ? public CDPlayer(CompactDisc cd){
this.cd = cd;
}
@Override
? ? public void play() {
cd.play();
}
}
@Component注解表明該類會(huì)作為組件類想括,并告知Spring為這個(gè)類創(chuàng)建bean
@Autowired注解表明當(dāng)Spring創(chuàng)建CDPlayer bean 的時(shí)候,會(huì)通過這個(gè)構(gòu)造器來進(jìn)行實(shí)例化并且會(huì)傳入一個(gè)可設(shè)置給CompactDisc類型的bean烙博。
@Autowired注解可以用在類的任何方法上瑟蜈,還可以用于成員變量上。@Inject源于Java依賴注入規(guī)范渣窜,在大多場(chǎng)景下可與@Autowired互換铺根。
然后定義一個(gè)SgtPeppers類,它實(shí)現(xiàn)了CompactDisc接口乔宿,也是一個(gè)組件類位迂。
package soundsystem;
import org.springframework.stereotype.Component;
@Component
public class SgtPeppers implements CompactDisc{
private String title ="Sgt. Pepper's Lonely Hearts Club Band";
private String artist ="The Beatles";
@Override
? ? public void play() {
System.out.println("Playing "+title+" by "+artist);
}
}
最后定義一個(gè)CDPlayer配置類
package soundsystem;
import org.springframework.context.annotation.*;
@Configuration
@ComponentScan
public class CDPlayerConfig {
}
@Configuration代表這是一個(gè)配置類
@ComponentScan表示啟用組件掃描
組件掃描可以在一個(gè)CD播放器一張CD的時(shí)候正常工作,但是在有兩張CD的時(shí)候就不能正常工作了详瑞,因?yàn)樗恢缿?yīng)該播放哪一張CD掂林,這里我們只有一張披頭士的CD,關(guān)于多張CD的情況留到后面處理坝橡。?
我們也可以用xml來實(shí)現(xiàn)組件掃描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
? ? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
? ? ? xmlns:context="http://www.springframework.org/schema/context"
? ? ? xmlns:c="http://www.springframework.org/schema/c"
? ? ? xmlns:p="http://www.springframework.org/schema/p"
? ? ? xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
? ? ? http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="soundsystem" />
</beans>
<context:component-scan base-package="soundsystem" />表示會(huì)在soundsystem這個(gè)包內(nèi)找合適的bean注入到CDplayer
現(xiàn)在定義CDPlayerTest類測(cè)試一下
package soundsystem;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
@Rule
? ? public final StandardOutputStreamLoglog =new StandardOutputStreamLog();
@Autowired
? ? private MediaPlayerplayer;
@Autowired
? ? private CompactDisccd;
@Test
? ? public void cdShouldNotNull(){
assertNotNull(cd);
}
@Test
? ? public void play(){
player.play();
assertEquals("Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\n",log.getLog());
}
}
@ContextConfiguration(classes = CDPlayerConfig.class)會(huì)使用CDPlayerConfig這個(gè)類來配置應(yīng)用上下文泻帮。
下面試試使用XML配置
package soundsystem;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations ="classpath:soundsystem.xml")
public class CDPlayerXMLConfigTest {
@Rule
? ? public final StandardOutputStreamLoglog =new StandardOutputStreamLog();
@Autowired
? ? private MediaPlayerplayer;
@Autowired
? ? private CompactDisccd;
@Test
? ? public void cdShouldNotNull(){
assertNotNull(cd);
}
@Test
? ? public void play(){
player.play();
assertEquals("Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\n",log.getLog());
}
}
@ContextConfiguration(locations ="classpath:soundsystem.xml")會(huì)使用soundsystem.xml來配置應(yīng)用上下文。
二计寇、Java顯式配置
媒體播放器和CD接口保持不變
接下來看看CD播放器類與自動(dòng)裝配有什么不同之處
package soundsystem;
import org.springframework.beans.factory.annotation.Autowired;
public class CDPlayer implements MediaPlayer {
private CompactDisccd;
? @Autowired
? public CDPlayer(CompactDisc cd) {
this.cd = cd;
? }
public void play() {
cd.play();
? }
}
與自動(dòng)裝配比較可以發(fā)現(xiàn)類聲明上面少了@Component注解 我們沒有將CDPlayer聲明為一個(gè)組件類
SgtPeppers類也沒有@Component注解
重點(diǎn)來看看CDplayerConfig類
package soundsystem;
import org.springframework.context.annotation.*;
@Configuration
public class CDPlayerConfig {
@Bean
? ? public CompactDisc compactDisc(){
return new SgtPeppers();
? ? }
@Bean
? ? public CDPlayer cdPlayer(CompactDisc cd){
return new CDPlayer(cd);
? ? }
}
這里沒有@ComponentScan注解然后在配置類中自己定義了兩個(gè)bean從第一個(gè)bean可以看到如果需要注入CompactDisc bean的時(shí)候注入的是SgtPeppers類對(duì)象锣杂,需要注入CDPlayer bean 時(shí)注入的時(shí)候注入的是CdPlayer對(duì)象。
總結(jié)一下:Java顯式配置與自動(dòng)裝配主要區(qū)別在配置類上番宁,Java配置需要顯示地聲明bean元莫,自動(dòng)裝配配置類有@ComponentScan注解,它會(huì)自動(dòng)掃描帶有@Component注解的bean來將其注入到合適的地方蝶押。
三踱蠢、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"
? xmlns:c="http://www.springframework.org/schema/c"
? xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
? <bean id="compactDisc" class="soundsystem.SgtPeppers" />
? <bean id="cdPlayer" class="soundsystem.CDPlayer"
? ? ? ? c:cd-ref="compactDisc" />
<bean id="compactDisc" class="soundsystem.SgtPeppers" />
@Bean
? ? public CompactDisc compactDisc(){
return new SgtPeppers();
? ? }
上述的一行XML配置和上面的一段Java配置起到的作用是一樣的。
XML中參數(shù)的聲明是由<constructor-arg>標(biāo)簽來實(shí)現(xiàn)播聪,想要注入一個(gè)集合可以使用<list>標(biāo)簽包裹集合內(nèi)所有項(xiàng)
使用<value>標(biāo)簽包裹集合內(nèi)的一項(xiàng)朽基。
<bean id="compactDisc"
? ? ? class="soundsystem.BlankDisc"
? ? ? c:_0="Sgt. Pepper's Lonely Hearts Club Band"
? ? ? c:_1="The Beatles">
c:_0代表構(gòu)造器的第一個(gè)參數(shù)布隔,c:_1代表構(gòu)造器的第二個(gè)參數(shù)。
四稼虎、混合配置
package soundsystem;
import org.springframework.context.annotation.*;
@Configuration
@Import(CDPlayerConfig.class)
@ImportResource("classpath:cd-config.xml")
public class SoundSystemConfig {
}
加粗的兩個(gè)注解從一個(gè)Java配置類和一個(gè)XML文檔加載上下文衅檀。