經(jīng)過(guò)將近五天的學(xué)習(xí) 坎坎坷坷地將第二章學(xué)完了 也算是走上了spring框架學(xué)習(xí)的正規(guī) 目前也僅僅懂一些為什么要用spring框架的原因 但不知道能用spring框架做什么 總而言之 還是繼續(xù)學(xué)吧燃乍。
我用的編譯器是Window10的idea 里面自帶Spring項(xiàng)目 因?yàn)榭磩e人的博客吃了很多苦 在這里先說(shuō)清楚 以免誤人子弟
博客講述方式將其代碼為主 所有的代碼都可以在我的github中找到(https://github.com/12Dong/learn-spring)
sprin配置可選方案
- 自動(dòng)化配置
- java配置
- xml配置
后兩者是顯示的 邏輯關(guān)系很明顯就能看出來(lái)
自動(dòng)化配置
Spring從兩個(gè)角度來(lái)實(shí)現(xiàn)自動(dòng)化配置
- 組件掃描(ComponentScan):Spring會(huì)自動(dòng)發(fā)現(xiàn)應(yīng)用上下文中所創(chuàng)建的bean
- 自動(dòng)裝配(Autowiring):Spring自動(dòng)滿足bean之間的依賴
自動(dòng)化配置樣例
實(shí)現(xiàn)·CompactDisc接口
package soundsystem;
public interface CompactDisc {
void play();
}
用一個(gè)類實(shí)現(xiàn)這個(gè)接口
package soundsystem;
import org.springframework.stereotype.Component;
@Component
public class SgtPeppers implements CompactDisc{
private String title = "舞動(dòng)青春";
private String artist = "廣播操";
public void play(){
System.out.print("Playing "+title+" by "+ artist);
}
}
Component 配件注解 表明將告知Spring要為這個(gè)Component創(chuàng)建Bean
組件掃描默認(rèn)是不開啟的 所以必須顯式開啟組件掃描
所以創(chuàng)建CDConfig.java進(jìn)行配置
開啟組件掃描
package soundsystem;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class CDPlayerConfig {
//這里沒有任何顯式配置
//在接下來(lái)的java配置這里將添加配置關(guān)系
}
如果沒有其他配置的話 @Component 將默認(rèn)掃描這個(gè)java文件所在package 查找?guī)?有@Component的類
此外還可以用xml開啟組件掃描 這里就不加累述
接下來(lái)就是困擾我將近兩天的Test測(cè)試框架了 我會(huì)單開一篇來(lái)講述我在配置Junit時(shí)遇到的問(wèn)題
package soundsystem;
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.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
@Autowired
private CompactDisc cd;
@Test
public void cdShouldNotBeNull(){
assertNotNull(cd);
}
}
然后就出現(xiàn)的結(jié)果是這樣子 no errors
通過(guò)為Bean添加注解實(shí)現(xiàn)自動(dòng)裝配
package explictUse.soundsystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
@Autowired(required = false)
/*
不管是構(gòu)造器 或者setter方法還是其他方法
Spring都會(huì)嘗試滿足方法參數(shù)上的申明的依賴
假如只有一個(gè)bean匹配依賴需求的話 那么這個(gè)bean將會(huì)被裝配進(jìn)來(lái)
如果沒有匹配的bean 那么在應(yīng)用上下文創(chuàng)建的時(shí)候
Spring會(huì)拋擲一個(gè)異常 為了避免這種異常 可以將Autowired設(shè)置為false
*/
public CDPlayer(CompactDisc cd){
this.cd = cd;
}
public void setCompactDisc(CompactDisc cd){
this.cd = cd;
}
public void play(){
cd.play();
}
}
這里可以看出CDPlayer需要組合一個(gè)CompactDisc類 同樣我們也可以使用自動(dòng)裝配為其配置compactDisc這個(gè)對(duì)象
驗(yàn)證自動(dòng)裝配
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
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 SystemOutRule systemOutRule = new SystemOutRule().enableLog();
@Autowired
private CompactDisc cd;
@Autowired
private MediaPlayer player;
@Test
public void cdShouldNotBeNull(){
assertNotNull(cd);
}
@Test
// public void play(){
// player.play();
// assertEquals("Playing 舞動(dòng)青春"+" by 廣播操\n",systemOutRule.getLog());
public void writesTextToSystemOut() {
player.play();
assertEquals("Playing 舞動(dòng)青春 by 廣播操", systemOutRule.getLog());
}
}
在這里寫的原書上略有不同 原書上的
import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
在我的編譯器中報(bào)錯(cuò)了
上網(wǎng)查證得知原庫(kù)無(wú)法使用
所以更為我用的方法
另外多次嘗試發(fā)現(xiàn)如果加了換行符 就匹配失敗 我也不知道為什么
結(jié)果圖如下
通過(guò)java代碼裝配bean
修改CDPlayerConfig中的代碼
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDPlayerConfig {
@Bean
public CompactDisc segPeppers(){
return new SgtPeppers();
}
// @Bean
// public CDPlayer cdPlayer(CompactDisc compactDisc){
// return new CDPlayer(compactDisc);
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
CDPlayer cdPlayer = new CDPlayer(compactDisc);
cdPlayer.setCompactDisc(compactDisc);
return cdPlayer;
}
}
Test驗(yàn)證
通過(guò)java配置config可以用一些常見的java代碼實(shí)現(xiàn) 比如說(shuō)setter函數(shù)之類的
通過(guò)xml裝備bean
xml在已擁有Spring自動(dòng)配置和基于Java配置的情況不多常用 學(xué)習(xí)xml多是維護(hù)已有的xml配置
spring框架中使用.xml后綴文件來(lái)代替JavaConfig的配置java文件
書上實(shí)例 BlankDisc中擁有原本屬性之外 還多一個(gè)list容器
<?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="xmlExplictUser.soundsystem.BlankDisc">-->
<!--<constructor-arg value = "舞動(dòng)青春" />-->
<!--<constructor-arg value = "廣播操"/>-->
<!--</bean>-->
<!--<bean id = "compactDisc" class="xmlExplictUser.soundsystem.BlankDisc"-->
<!--c:_0 ="舞動(dòng)青春"-->
<!--c:_1="廣播操" />-->
<bean id="compactDisc" class="xmlExplictUser.soundsystem.BlankDisc">
<constructor-arg value="廣播操"/>
<constructor-arg value="廣播臺(tái)"/>
<constructor-arg>
<list>
<value>舞動(dòng)青春</value>
<value>時(shí)代在召喚</value>
<value>初生的太陽(yáng)</value>
</list>
</constructor-arg>
</bean>
</beans>
Test測(cè)試一下
import static org.junit.Assert.*;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import xmlExplictUser.soundsystem.BlankDisc;
public class BlankDiscTest {
@Test public void instanceSpring(){
AbstractApplicationContext context = new ClassPathXmlApplicationContext("xmlExplictUserBean.xml");
BlankDisc compactDisc = (BlankDisc)context.getBean("compactDisc");
compactDisc.play();
// context.close();
}
}
混合配置
通過(guò)java+xml配置依賴關(guān)系
package xmlExplictUser.soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDConfig {
@Bean
public CompactDisc compactDisc(){
return new SgtPeppers();
}
}
有點(diǎn)蒙圈... ...等清醒一點(diǎn)再寫