IOC容器的概念
IOC容器就是具有依賴注入功能的容器案狠,IOC容器負(fù)責(zé)實(shí)例化钱雷、定位、配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴从铲。應(yīng)用程序無(wú)需直接在代碼中new相關(guān)的對(duì)象澄暮,應(yīng)用程序由IOC容器進(jìn)行組裝阱扬。在Spring中BeanFactory是IOC容器的實(shí)際代表者。
Spring IOC容器如何知道哪些是它管理的對(duì)象呢馍刮?這就需要配置文件窃蹋,Spring IOC容器通過(guò)讀取配置文件中的配置元數(shù)據(jù),通過(guò)元數(shù)據(jù)對(duì)應(yīng)用中的各個(gè)對(duì)象進(jìn)行實(shí)例化及裝配警没。一般使用基于xml配置文件進(jìn)行配置元數(shù)據(jù),而且Spring與配置文件完全解耦的亡脸,可以使用其他任何可能的方式進(jìn)行配置元數(shù)據(jù),比如注解浅碾、基于java文件的、基于屬性文件的配置都可以厦画。
Bean的概念
由IOC容器管理的那些組成你應(yīng)用程序的對(duì)象我們就叫它Bean滥朱, Bean就是由Spring容器初始化、裝配及管理的對(duì)象,除此之外晨另,bean就與應(yīng)用程序中的其他對(duì)象沒(méi)有什么區(qū)別了。那IOC怎樣確定如何實(shí)例化Bean、管理Bean之間的依賴關(guān)系以及管理Bean呢薇芝?這就需要配置元數(shù)據(jù)丰嘉,在Spring中由BeanDefinition代表,后邊會(huì)詳細(xì)介紹饮亏,配置元數(shù)據(jù)指定如何實(shí)例化Bean、如何組裝Bean等荐开。概念知道的差不多了简肴,讓我們來(lái)做個(gè)簡(jiǎn)單的例子。
開始Spring Hello World之旅
1 創(chuàng)建接口
public interface HelloService {
public void sayHello();
}
2 實(shí)現(xiàn)接口
public class HelloServiceImpl implements HelloService{
public void sayHello(){
System.out.println("Hello World!");
}
}
3 配置文件配置
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- id 表示組件的名字能扒,class表示組件類 -->
<bean id="helloService" class="com.test.HelloServiceImpl" />
</beans>
4 實(shí)際運(yùn)用
public class Program{
public staic void main(String[] args) {
// 1辫狼、讀取配置文件實(shí)例化一個(gè)IOC容器
ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml");
// 2、從容器中獲取Bean膨处,注意此處完全“面向接口編程频蛔,而不是面向?qū)崿F(xiàn)”
HelloService helloService = context.getBean("helloService", HelloService.class);
// 3晦溪、執(zhí)行業(yè)務(wù)邏輯
helloService.sayHello();
}
}
詳解IOC容器
在Spring IOC容器的代表就是org.springframework.beans包中的BeanFactory接口挣跋,BeanFactory接口提供了IOC容器最基本功能;而org.springframework.context包下的ApplicationContext接口擴(kuò)展了BeanFactory避咆,還提供了與Spring AOP集成、國(guó)際化處理路媚、事件傳播及提供不同層次的context實(shí)現(xiàn) (如針對(duì)web應(yīng)用的WebApplicationContext)樊销。簡(jiǎn)單說(shuō), BeanFactory提供了IOC容器最基本功能围苫,而 ApplicationContext 則增加了更多支持企業(yè)級(jí)功能支持。ApplicationContext完全繼承BeanFactory拧揽,因而BeanFactory所具有的語(yǔ)義也適用于ApplicationContext腺占。
容器實(shí)現(xiàn)一覽:
? XmlBeanFactory:BeanFactory實(shí)現(xiàn),提供基本的IOC容器功能衰伯,可以從classpath或文件系統(tǒng)等獲取資源;
File file = new File("fileSystemConfig.xml");
Resource resource = new FileSystemResource(file);
BeanFactory beanFactory = new XmlBeanFactory(resource);
Resource resource = new ClassPathResource("classpath.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
? ClassPathXmlApplicationContext:ApplicationContext實(shí)現(xiàn),從classpath獲取配置文件临扮;
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath.xml");
? FileSystemXmlApplicationContext:ApplicationContext實(shí)現(xiàn)教翩,從文件系統(tǒng)獲取配置文件。
BeanFactory beanFactory = new FileSystemXmlApplicationContext("fileSystemConfig.xml");
讓我們來(lái)看下IOC容器到底是如何工作饱亿。在此我們以xml配置方式來(lái)分析一下:
一闰靴、準(zhǔn)備配置文件:就像前邊Hello World配置文件一樣钻注,在配置文件中聲明Bean定義也就是為Bean配置元數(shù)據(jù)。
二杏死、由IOC容器進(jìn)行解析元數(shù)據(jù): IOC容器的Bean Reader讀取并解析配置文件捆交,根據(jù)定義生成BeanDefinition配置元數(shù)據(jù)對(duì)象,IOC容器根據(jù)BeanDefinition進(jìn)行實(shí)例化品追、配置及組裝Bean。
三遭京、實(shí)例化IOC容器:由客戶端實(shí)例化容器风宁,獲取需要的Bean。
整個(gè)過(guò)程是不是很簡(jiǎn)單戒财,執(zhí)行過(guò)程如下饮寞,其實(shí)IOC容器很容易使用,主要是如何進(jìn)行Bean定義幽崩。下一章我們?cè)敿?xì)介紹定義Bean。
總結(jié)
除了測(cè)試程序的代碼外陌选,也就是程序入口蹄溉,所有代碼都沒(méi)有出現(xiàn)Spring任何組件,而且所有我們寫的代碼沒(méi)有實(shí)現(xiàn)框架擁有的接口柒爵,因而能非常容易的替換掉Spring棉胀,是不是非入侵冀膝。
客戶端代碼完全面向接口編程霎挟,無(wú)需知道實(shí)現(xiàn)類,可以通過(guò)修改配置文件來(lái)更換接口實(shí)現(xiàn)氓扛,客戶端代碼不需要任何修改。是不是低耦合千所。
如果在開發(fā)初期沒(méi)有真正的實(shí)現(xiàn)蒜埋,我們可以模擬一個(gè)實(shí)現(xiàn)來(lái)測(cè)試,不耦合代碼整份,是不是很方便測(cè)試。
Bean之間幾乎沒(méi)有依賴關(guān)系火俄,是不是很容易重用讲冠。