1.IOC 控制反轉(Inversion of Control)html
控制反轉是一種設計原則,用來下降代碼之間的耦合性。其中最多見的方式叫作依賴注入(DI)經過控制反轉,對象在被建立的時候,系統內全部對象將經過配置文件(XML,JavaCode,註解等...)配置的依賴的對象的引用傳遞給它。也能夠說,依賴被注入到對象中。java
容器(Container)容器的做用就是生成(生命週期開始時)、存放bean的實例並控制每一個bean實例的生命週期 ,在適當的時候銷燬bean實例(生命週期結束時)。web
Spring框架支持六個做用域,其中四個只有在使用Web感知的ApplicationContext時纔可用。也能夠建立自定義範圍。spring
做用域編程 |
描述api |
singleton(單例)session |
(默認)SpringIoC容器爲每一個bean定義只建立一個對象實例app |
prototype(原型)框架 |
每次調用都將建立對象實例。socket |
request(請求) |
每次HTTP請求都會建立本身的bean實例。僅僅使用Web感知的ApplicationContext時纔可用。 |
session(會話) |
每一個會話都會建立本身的bean實例。僅僅使用Web感知的ApplicationContext時纔可用。 |
application(應用) |
在ServletContext的生命週期中使用單個bean定義. 僅僅使用Web感知的ApplicationContext時纔可用。 |
Websocket(Websocket) |
將單個bean定義做用於WebSocket的生命週期。僅僅使用Web感知的ApplicationContext時纔可用。 |
IoC模式中,系統經過引入實現了IoC模式的IoC容器,便可由IoC容器來管理對象的生命週期、依賴關係等,從而使得應用程序的配置和依賴性規範與實際的應用程序代碼分離。其中一個特色就是經過文本的配置文件進行應用程序組件間相互關係的配置,而不用從新修改並編譯具體的代碼。
能夠把IoC模式看做工廠模式的昇華,把IoC容器看做是一個大工廠,只不過這個大工廠裏要生成的對象都是在配置文件(XML,JavaCode,註解等...)中給出定義的。利用Java 的「反射」編程,根據配置文件(XML,JavaCode,註解等...)中給出的類定義生成相應的對象。從實現來看,之前在工廠模式裏寫死了的對象,IoC模式改成配置文件(XML,JavaCode,註解等...),這就把工廠和要生成的對象二者隔離,極大提升了靈活性和可維護性
1.一、BeanFactory
org.springframework.beans 和org.springframework.context 包是Spring 框架IOC容器的基礎。BeanFactory 接口提供了一種高級配置機制,可以管理任何類型的對象。ApplicationContext 是BeanFactory的子接口。
BeanFacotry是spring中比較原始的Factory。如XMLBeanFactory就是一種典型的BeanFactory。原始的BeanFactory沒法支持spring的許多插件,如AOP功能、Web應用等。
ApplicationContext接口,它由BeanFactory接口派生而來,ApplicationContext包含BeanFactory的全部功能,一般建議優先使用ApplicationContext
1 Resource resource = new FileSystemResource("beans.xml"); 2 BeanFactory factory = new XmlBeanFactory(resource);
1 ClassPathResource resource = new ClassPathResource("beans.xml"); 2 BeanFactory factory = new XmlBeanFactory(resource);
1 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"}); 3 BeanFactory factory = (BeanFactory) context;
BeanFacotry 提供了六種方法供用戶調用
參考:Spring BeanFactory與FactoryBean的區別及其各自的詳細介紹於用法
org.springframework.context.ApplicationContext接口表示SpringIoC容器,負責實例化、配置和組裝bean。 BeanFactory 提供了配置框架和基本功能,ApplicationContext 添加了更多特定於企業的功能。ApplicationContext 是一個完整的BeanFactory 的擴展集
ApplicationContext 的實現類有FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。
ClassPathXmlApplicationContext 默認從類路徑加載配置文件,FileSystemXmlApplicationContext 默認從文件系統中裝載配置文件
和BeanFactory初始化類似,ApplicationContext的初始化也很簡單,若是配置文件放置在類路徑下,用戶能夠優先使用ClassPathXmlApplicationContext實現類:
ApplicationContext ctx = new ClassPathXmlApplicationContext(「com/baobaotao/context/beans.xml」)
對於ClassPathXmlApplicationContext來講,」com/baobaotao/context/beans.xml」等同於」classpath: com/baobaotao/context/beans.xml」。
若是配置文件放置在文件系統的路徑下,則能夠優先考慮使用FilySystemXmlApplicationContext實現類:
ApplicationContext ctx =new FileSystemXmlApplicationContext(「com/baobaotao/context/beans.xml」);
對於FileSystemXmlApplicationContext來講,「com/baobaotao/context/beans.xml」等同於「file:com/baobaotao/context/beans.xml」。
還能夠指定一組配置文件,Spring會自動將多個配置文件在內存中」整合」成一個配置文件,以下所示:
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{「conf/beans1.xml」,」conf/beans2.xml」});
ApplicationContext的初始化和BeanFactory有一個重大的區別:BeanFactory在初始化容器時,並未實例化Bean,直到第一次訪問某個Bean時才實例目標Bean;而ApplicationContext則在初始化應用上下文時就實例化全部單實例的Bean。所以ApplicationContext的初始化時間會比BeanFactory稍長一些,不過稍後的調用則沒有」第一次懲罰」的問題。
WebApplicationContext 繼承了ApplicationContext接口,是ApplicationContext的擴展,它增長了WEB應用特性,還能夠視圖解析、主題解析、映射,經過ServletContext與servlet關聯 ,WebApplicationContext被綁定在ServletContext上(經過ContextLoaderListener綁定),能夠經過RequestContextUtils獲取WebApplicationContext。
WebApplicationContext是專門爲web應用準備的,他容許從相對於web根目錄的路勁中裝載配置文件完成初始化工做,從WebApplicationContext中能夠得到ServletContext的引用,整個Web應用上下文對象將做爲屬性放置在ServletContext中,以便web應用能夠訪問spring上下文,spring中提供WebApplicationContextUtils的getWebApplicationContext(ServletContext src)方法來得到WebApplicationContext對象
WebApplicationContext擴展了ApplicationContext.在 WebApplicationContext中定義了一個常量 ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,在上下文啓動時,WebApplicationContext以此爲鍵放置在ServletContext屬性列表中,
public static WebApplicationContext getWebApplicationContext(ServletContext sc) { return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); }
ConfigurableWebApplicationContext擴展了WebApplicationContext,它容許經過配置的方式實例化,同時設置兩個重要方法
setServletContext(ServletContext context) 爲spring設置web應用上下文,以便二者整合
setConfigLocations(String[]locations) 設置Spring配置的文件地址
webApplicationContext初始化須要ServletContext,也就是說須要web容器前提下才能·完成啓動工做 能夠經過在web.xml中配置自啓動Servlet或Web容器監聽來實現web容器的啓動
Spring分別提供啓動WebApplicationContext的servlet和Web容器監聽器
org.springframework.web.context.ContextLoaderListener
org.springframework.web.context.ContexLoaderServlet 此方法目前以廢棄
!--從類路徑下加載Spring配置文件,classpath特指類路徑下加載--> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:smart-context.xml </param-value> </context-param> <!--負責啓動spring容器的監聽器 還能夠聲明自啓動的Servlet ContextLoaderServlet--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
若是使用@Configuration的java類提供配置信息的配置 web.xml配置修改以下
<!--經過指定context參數,讓Spring使用AnnotationConfigWebApplicationContext啓動容器而非XmlWebApplicationContext 默認沒配置時是使用XmlWebApplicationContext--> <context-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext </param-value> </context-param> <!--指定標註了@Configuration的類,多個能夠用逗號分隔--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>com.example.Car,com.example.Boss</param-value> </context-param> <!--監聽器將根據上面的配置使用AnnotationConfigWebApplicationContext 根據contextConfigLocation 指定的配置類啓動Spring容器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
1.4 配置元數據
SpringIoC容器使用一種配置元數據。此配置元數據展現了Spring 容器如何在應用程序中實例化、配置和組裝對象。
Spring容器支持基於XML的配置元數據配置,Spring2.5引入了對基於註釋的配置元數據的支持,從Spring3.0開始,Spring JavaConfig 項目提供的許多特性成爲核心Spring框架的一部分,引入了對基於Java的配置元數據的支持。
基於XML的配置元數據將這些bean配置爲在頂層元素<beans/>內部的<bean/>元素。Java配置一般在帶有@Configuration註釋的類中使用帶@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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="..." class="..."> ① ② <!-- collaborators and configuration for this bean go here --> <!-這個bean的協做者(引用其餘的bean)和配置在這裏-> </bean> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> <!-這個bean的協做者和配置在這裏-> </bean> <!-- more bean definitions go here --> <!-更多的bean配置在這裏-> </beans>
<bean>中 id屬性是標識單個bean定義的字符串,class屬性定義Bean的類型,並使用徹底限定的類名稱。
基於Java的配置元數據的基本結構:
@Configuration public class SpringConfig { @Bean public Piano piano(){ return new Piano(); } @Bean(name = "counter") public Counter counter(){ return new Counter(12,"Shake it Off",piano()); } }