上一篇:Spring學(xué)習(xí)筆記(二咆贬、Spring框架)
接口
- 用于溝通的中介物的抽象化;
- 實體把自己提供給外界的一種抽象化說明帚呼,用以由內(nèi)部操作分離出外部溝通的方法掏缎。使其能被修改內(nèi)部而不影響外界其他實體與其交互的方式;
- 對應(yīng)java接口即聲明煤杀,聲明了哪些方法是對外公開提供的眷蜈;
- 在Java8中,接口可以擁有方法體怜珍。
根據(jù)上述內(nèi)容端蛆,簡述我自己對接口的見簡單理解:
接口是外界能看到的,實體是外界看不到的酥泛,所以接口在程序中是實體和外界其他實體溝通的橋梁,類似中介嫌拣。
面向接口編程
- 結(jié)構(gòu)設(shè)計中柔袁,分清層次及調(diào)用關(guān)系,每層只向外(上層)提供一組功能接口异逐,各層次間依賴接口而非實現(xiàn)類捶索。
- 接口實現(xiàn)的變動不影響各層間的調(diào)用,這一點在公共服務(wù)中尤為重要灰瞻。
- “面向接口編程”中的“接口”是用于隱藏具體實現(xiàn)和實現(xiàn)多態(tài)性的組件腥例。
什么是IoC
- IoC:控制反轉(zhuǎn)辅甥,控制權(quán)的轉(zhuǎn)移,應(yīng)用程序本身不負(fù)責(zé)依賴對象的創(chuàng)建和維護(hù)燎竖,而是由外部程序創(chuàng)建和維護(hù)璃弄。
- DI(依賴注入)是其一種實現(xiàn)方式
- 目的:創(chuàng)建對象并且組裝對象之間的依賴關(guān)系
根據(jù)上述內(nèi)容,簡述我自己對IOC簡單理解:
舉個例子:我們要住宿构回,首先我們不可能蓋個房子夏块、裝修好才去住宿。事實上纤掸,我們只需要找家賓館脐供,它會給我們提供房間,就可以住宿了借跪。
IOC就相當(dāng)與賓館政己,它為我們提供了創(chuàng)建好的對象,我們直接使用就好了掏愁。這就是控制權(quán)的反轉(zhuǎn)匹颤,我們把自己創(chuàng)建對象的權(quán)利,交給IOC去完成托猩。
Spring中的Bean配置
舉例說明:
接口
實現(xiàn)接口的類即實體
Bean配置
測試
控制臺輸出
這個例子讓我們發(fā)現(xiàn):
- 在程序中印蓖,我們不必自己new對象,因為IoC容器提供了京腥。
- 實現(xiàn)了面向接口編程赦肃,并且IoC把實現(xiàn)隱藏了,讓我們在調(diào)用的時候公浪,完全看不到實現(xiàn)他宛。
- 這個例子是使用的xml配置bean的方法。
細(xì)心的小伙伴欠气,可能發(fā)現(xiàn)測試使用junit厅各,關(guān)于junit,請參考:JUnit 4 簡介和單元測試之JUnit预柒,這兩篇寫得都比較容易理解队塘,互相參考融合知識點于自己。
IoC容器的初始化過程
- 基礎(chǔ):兩個包
org.springframework.beans
org.springframework.context
BeanFactory提供配置結(jié)構(gòu)和基本功能宜鸯,加載并初始化Bean
ApplicationContext保存了Bean對象并在Spring中被廣泛使用
- 方式:(初始化ApplicationContext.xml文件)
- 本地文件:
FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("本地絕對路徑");
* Classpath:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("項目相對路徑憔古,如:classpath*:spring-ioc.xml");
* Web應(yīng)用中依賴servlet或Listener
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet_name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderListener</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Spring注入
- Spring注入是指在啟動Spring容器加載bean配置的時候,完成對變量的賦值行為淋袖。
- 常用的兩種注入方式:
- 設(shè)值注入
- 構(gòu)造注入
########下面依次做測試:
-
設(shè)值注入
main目錄下鸿市,創(chuàng)建如下結(jié)構(gòu):
TestDao:
TestDaoImpl:
TestService:
重點來了!!焰情!TestServiceImpl:
別忘了在spring-ioc.xml里配置bean哦~
看到這里陌凳,設(shè)值注入其實就是setter方式注入。
如果會用JUnit的話内舟,可以在執(zhí)行下方的方法測試哦~
為了方便快速上手合敦,我將JUnit測試,提出來的父類共享出來:
package base;
import com.sun.corba.se.spi.ior.ObjectKey;
import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;
/**
* Created by amber on 2017/5/23.
*/
public class UnitTestBase {
private ClassPathXmlApplicationContext context;
private String springXmlPath;
public UnitTestBase() {
}
public UnitTestBase(String springXmlPath) {
this.springXmlPath = springXmlPath;
}
@Before
public void before() {
if (StringUtils.isEmpty(springXmlPath)) {
springXmlPath = "classpath*:spring-*.xml";
}
try {
context = new ClassPathXmlApplicationContext(springXmlPath.split("[,\\s]+"));
context.start();
} catch (BeansException e) {
e.printStackTrace();
}
}
@After
public void after() {
context.destroy();
}
protected <T extends Object> T getBean(String beanId) {
try {
return (T)context.getBean(beanId);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
}
測試用例:
package ioc;
import base.UnitTestBase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import test3.service.TestService;
/**
* Created by amber on 2017/5/26.
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class TestOneInterface extends UnitTestBase {
public TestOneInterface() {
super("classpath*:spring-ioc.xml");
}
@Test
public void test3() {
TestService testService = super.getBean("testService");
testService.save("學(xué)習(xí)設(shè)值注入中……");
}
}
- 構(gòu)造注入
TestServiceImpl增加如下構(gòu)造代碼:
//構(gòu)造器注入
public TestServiceImpl(TestDao testDao) {
this.testDao = testDao;
}
Spring-ioc.xml先注釋掉之前的設(shè)值注入谒获,增加構(gòu)造注入配置:
<bean id="testService" class="test3.service.TestServiceImpl">
<constructor-arg name="testDao" ref="testDao"/>
</bean>
最后測試就可以了蛤肌。很簡單的!
這里需要注意的是:
- 設(shè)值注入批狱,要保證bean中name必須要和被調(diào)用類屬性一致裸准。
- 構(gòu)造注入,name的值要保證和被調(diào)用類的構(gòu)造的參數(shù)一致赔硫。