Spring的測(cè)試框架和ApplicationContext配置文件
一借宵、ApplicationContext的實(shí)現(xiàn)類
1.1 使用FileSystemXmlApplicationContext獲取spring配置文件
Application.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<description>Spring Quick Start</description>
<bean id="TheAction1" class="com.example.service.LowerAction">
<property name="prefix">
<value>Hi</value>
</property>
<property name="message">
<value>Good Morning</value>
</property>
</bean>
<bean id="TheAction2" class="com.example.service.LowerAction">
<constructor-arg index="0">
<value>Hi</value>
</constructor-arg>
<constructor-arg index="1">
<value>Good Afternoon</value>
</constructor-arg>
</bean>
</beans>
使用FileSystemXmlApplicationContext來獲取spring配置文件
@Test
public void test1() {
String XML = "file:src/applicationContext.xml";
ApplicationContext ctx = new FileSystemXmlApplicationContext(XML);
Action action = (Action) ctx.getBean("TheAction1");
action.execute("Rod Johnson4");
}
實(shí)驗(yàn)結(jié)果如下:
想到的問題 FileSystemXmlApplicationContext 的路徑
沒有盤符的是項(xiàng)目工作路徑,即項(xiàng)目的根目錄毡泻;
有盤符表示的是文件絕對(duì)路徑喧锦。
一般用file:作為前綴癌椿,也可以省略
使用絕對(duì)路徑:
@Test
public void test1() {
String XML="file:/Users/wushuohan/IdeaProjects/hello/src/applicationContext.xml";
ApplicationContext ctx = new FileSystemXmlApplicationContext(XML);
Action action = (Action) ctx.getBean("TheAction1");
action.execute("Rod Johnson4");
}
實(shí)驗(yàn)中碰到的問題
在實(shí)驗(yàn)中一開始只注釋掉了@ContextConfiguration罩旋,而忘記注釋掉@RunWith无虚。
錯(cuò)誤代碼如下:
@RunWith(SpringRunner.class)
//@ContextConfiguration(locations={"file:src/applicationContext.xml"})
public class Test2_InJunit {
@Test
public void test1() {
String XML = "file:src/applicationContext.xml";
ApplicationContext ctx = new FileSystemXmlApplicationContext(XML);
Action action = (Action) ctx.getBean("TheAction1");
action.execute("Rod Johnson4");
}
程序報(bào)錯(cuò)如下:
錯(cuò)誤原因
@RunWith是一個(gè)運(yùn)行器边涕,而@ContextConfiguration指定 Spring 配置文件所在的位置晤碘。
@RunWith(SpringRunner.class)讓測(cè)試運(yùn)行于Spring測(cè)試環(huán)境,Spring框架在org.springframework.test.annotation 包中提供功蜓。
因?yàn)锳ction1是我自己在XML里定義的bean园爷,而我這里只使用了@RunWith導(dǎo)致了程序拋出空指針異常,因?yàn)椴]有被初始化的相應(yīng)Bean對(duì)象式撼。
從這個(gè)問題中我們可以近一步考慮Spring容器與Bean之間的關(guān)系:
ApplicationContext ctx=new ClassPathXmlApplicationContext("file:src/ApplicationContext.xml");
Action action = (Action)ctx.getBean("TheAction1");
在創(chuàng)建ApplicationContext實(shí)例對(duì)象過程中會(huì)創(chuàng)建一個(gè)spring容器童社,該容器會(huì)讀取配置文件" file:src/ApplicationContext.xml ",并統(tǒng)一管理由該文件中定義好的所有bean實(shí)例對(duì)象端衰。
如果要獲取某個(gè)bean實(shí)例叠洗,使用getBean方法就行了。
因此只需要將Action提前配置在xml文件中旅东,之后可以不需使用new Action()的方式創(chuàng)建實(shí)例灭抑,而是通過容器來獲取實(shí)例,這就相當(dāng)于將Action的控制權(quán)交由spring容器了抵代。
1.2使用ClassPathXmlApplicationContext獲取Spring配置文件
測(cè)試函數(shù)如下:
@Test
public void test2() {
String XML = "file:src/applicationContext.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext("src/applicationContext.xml");
Action action1 = (Action) ctx.getBean("TheAction1");
action1.execute("Rod Johnson5");
}
實(shí)驗(yàn)結(jié)果如下所示:
想到的問題:ClassPathXmlApplicationContext的路徑有哪些寫法腾节?
默認(rèn)的是讀取classes文件夾下的文件,可以在前面加上classpath,不加也可以荤牍。
用file作前綴加上絕對(duì)路徑也可以案腺。
實(shí)驗(yàn)中碰到的問題1:classpath在哪里?
一開始直接把XML文件放在TARGET的CLASSES下面康吵,報(bào)錯(cuò)如下:
打印classpath劈榨,在控制臺(tái)里查看具體路徑:
@Test
public void testt(){
String s[] = System.getProperty("java.class.path").split(";");
for (String string : s) {
System.out.println(string);
}
}
打印結(jié)果如下:
還是不知道在哪里……
最后我把XML文件直接放在Resource文件夾下:
測(cè)試成功:
1.3使用 @ContextConfiguration(locations={……})獲取Spring配置文件
測(cè)試代碼如下:
@RunWith(SpringRunner.class)
@ContextConfiguration(locations={"file:src/applicationContext.xml"})
public class Test2_InJunit {
@Test
public void test3() {
action1.execute("Rod Johnson5");
}
@Autowired
@Qualifier("TheAction1")
Action action1;
}
實(shí)驗(yàn)結(jié)果如下:
實(shí)驗(yàn)中想到的問題:為什么不再需要像之前那樣getBean()晦嵌?
因?yàn)橛蠤Autowired同辣。
Spring 通過一個(gè) BeanPostProcessor 對(duì) @Autowired 進(jìn)行解析拷姿,所以要讓 @Autowired 起作用必須事先在 Spring 容器中聲明 AutowiredAnnotationBeanPostProcessor Bean。
Spring 容器啟動(dòng)時(shí)旱函,AutowiredAnnotationBeanPostProcessor 將掃描 Spring 容器中所有 Bean响巢,當(dāng)發(fā)現(xiàn) Bean 中擁有 @Autowired 注釋時(shí)就找到和其匹配(默認(rèn)按類型匹配)的 Bean,并注入到對(duì)應(yīng)的地方中去棒妨。
實(shí)驗(yàn)中碰到的問題:
XML文件里的Bean太多踪古,報(bào)錯(cuò)如下
解決方法,在@AutoWired下加上@Qualifier
@Test
public void test3() {
action1.execute("Rod Johnson5");
action2.execute("Rod Johnson5");
}
@Autowired
@Qualifier("TheAction1")
Action action1;
@Autowired
@Qualifier("TheAction2")
Action action2;
本章的總結(jié)
BeanFactory和ApplicationContext是Spring的兩大核心接口券腔,其中ApplicationContext是BeanFactory的子接口伏穆。
它們都可以當(dāng)作Spring的容器,Spring容器是生成Bean實(shí)例的工廠颅眶,并管理容器中的Bean蜈出。在基于Spring的Java EE應(yīng)用中,所有的組件都被當(dāng)成Bean處理涛酗,包括數(shù)據(jù)源铡原,Hibernate的SessionFactory、事務(wù)管理器等商叹。
BeanFactory負(fù)責(zé)配置燕刻、創(chuàng)建、管理Bean剖笙,還管理著Bean和Bean之間的依賴關(guān)系卵洗。
ApplicationContext常用的實(shí)現(xiàn)類是:
FileSystemXmlApplicationContext
ClassPathXmlApplicationContext
AnnotationConfigApplicationContext
除了提供BeanFactory所支持的所有功能外,ApplicationContext還有額外的功能,如資源訪問弥咪,比如訪問URL和文件过蹂、同時(shí)加載多個(gè)配置文件、以聲明方式啟動(dòng)并創(chuàng)建Spring容器等