Hello,你們好,今天開始,小弟準備推出Spring系列的博客,但願你們喜歡。關於Spring其實我就不用再多介紹了,作過Web開發的,基本都使用Spring,包括如今比較時尚的Spring cloud微服務架構,其實也是基於Spring boot ,Spring boot 說到底其實仍是傳統的Spring三件套,只是避免了用戶本身配置Bean,而是採用了自動配置,Spring boot後期有時間也專門給你們出一系列博客。這一期做爲Spring的第一篇,先來點基礎的,OK,來套路,文章結構:java
其實對於不少業務開發程序員來說,這個接口是比較陌生的,你們知道的是在初始化容器的時候直接指定文件路徑,而後容器就初始化好了,這個Resource接口是Spring提供的,它爲應用提供了更強的底層資源訪問能力。比JDK自帶的File和URL類不知道強了多少。列下類結構: 程序員
說幾個重點的: ClassPathResource: 以類路徑爲相對路勁下的資源 。 FileSystemResource : 以文件系統路徑查找的資源。 ServletContextResource : 以相對於Web應用跟目錄的方式訪問。 ByteArrayResource: 二進制數組表示的資源。 好比如今Web的路徑下又一個Spring的配置文件,咱們能夠這樣加載:Resource res =new ServletContectResource(/WEB-INF/classes/spring/application.xml);
複製代碼
看到代碼,相信比較敏感的小夥伴應該感受到了,這種加載方式顯然是不合適的,由於在使用不一樣的資源類型時,必須使用相應的Resource資源類,這是比較麻煩的,是否能夠在不現實使用Resource實現類的狀況下,僅經過資源地址的特殊標識就能夠訪問相應的資源呢?Spring這麼偉大的框架,固然是能夠的。Spring不只可以經過"classpath:","file"等資源地址前綴識別不一樣資源類型,還支持Ant風格帶通配符的資源地址。Spring內部會經過資源加載器來根據不一樣的資源路徑選擇相應的Resource實現類。避免的使用者本身選擇實現類。web
先看下Spring內置的一些資源前綴表達的含義: spring
而後Ant風格:具體就不舉例子了,Ant風格的通配符太經常使用了。sql
public class GaoshiApplication {
public static void main(String[] args) throws IOException {
PathMatchingResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
Resource[] res =resolver.getResources("file:/Users/zdy/Desktop/sql.txt");
for (Resource resource : res){
System.out.println(resource.getDescription()+"----"+resource.getFilename());
}
SpringApplication.run(GaoshiApplication.class, args);
}
}
複製代碼
輸出結果:
URL [file:/Users/zdy/Desktop/sql.txt]----sql.txt
複製代碼
好了,其實這一小節爲何要給你們講Resource和PathMatchingResourcePatternResolver資源加載器呢,不少人可能感受沒什麼用,反正Spring內部本身使用就完了,跟我不要緊。其實不是的,老鐵們,Spring內部本身使用不假,首先,知道點底層原理很差嗎?其次,你們若是本身有配置文件在classpath下,而後想經過代碼去加載(雖然這種需求很是少),那麼你們就能夠本身使用Spring提供的資源加載器了。這個加載器仍是很方便的,直接根據前綴加載資源,並且還支持Ant通配符。你說厲害不厲害。數組
BeanFactory,其實不少人聽過,只是沒有用過,你們啓動容器的時候可能都是用的ApplicationContext的某個實現類,因此這個BeanFactory慢慢的都淡了,更別說它的實現類了。說下特性:bash
而後舉個初始化BeanFactory的例子吧:session
//調用資源加載器加載Spring配置文件
PathMatchingResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
Resource res =resolver.getResource("classpath:/application.xml");
//建立默認Spring提供的BeanFactory實現類
DefaultListableBeanFactory bf =new DefaultListableBeanFactory();
//BeanDefinition 讀取器,專門讀取資源到容器
XmlBeanDefinitionReader reader =new XmlBeanDefinitionReader(bf);
//讀取資源進到容器
reader.loadBeanDefinitions(res);
//此時容器初始化完畢後能夠取裏面的bean了.
bf.getBean("...");
複製代碼
能夠看到,代碼比較繁瑣,並且很囉嗦。BeanFactory的功能還比較弱,因此你們就當瞭解吧。架構
這個ApplicationContext其實就是老鐵們常常說的Spring容器了。由於相對要重要一些,因此列了大體的類繼承圖: app
說下圖中幾個重要的類或接口:ApplicationContext ac =new ClassPathXmlApplicationContext("application.xml");
ApplicationContext ac =new FileSystemXmlApplicationContext(/User/Desktop/application.xml);
複製代碼
ClassPathXmlApplicationContext若是沒有前綴默認就是classpath: FileSystemXmlApplicationContext若是沒有前綴默認就是 file:
而後再說一個,Spring容器不只能夠經過xml文件來初始化,@Configuration註解你們應該知道,也是註冊Bean用的,固然了,Spring也提供了相應的AnnotationConfigApplicationContext.
ApplicationContext context =new AnnotationConfigApplicationContext(Config.class);
複製代碼
Config類就是咱們加了@Configuration的類了。
其實WebApplicationContext也屬於ApplicationContext,爲何單獨拿出來說呢,由於比較重要。WebApplicationContext是Spring專門爲Web應用準備的。它容許從相對於Web根目錄的路徑中裝載配置文件完成初始化工做。WebApplicationContext與ServletContext能夠相互得到.在非Web應用的環境下,Bean只有singleton和prototype兩種做用域,而WebApplicationContext爲Bean添加了三個新的做用域:request,session,global session。來看下類繼承圖:
最最核心的XmlWebApplicationContext和AnnotationConfigWebApplicationContext,你們猜都應該猜到了,一個是XML配置的,一個是@Configuration配置的。而後說下WebApplicationContext和ServletContext是如何相互獲取的,其實很簡單,在WebApplicationContext裏有ServletContext成員變量,直接get就完了。在ServletContext裏有一個寫死的attrbute,也是直接get..並且Spring提供了一個WebApplicationContextUtils來封裝了這個寫死的attribute.
其實就是直接調用了ServletContext.getAttribute(ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}
複製代碼
而後說下WebApplication的初始化,作過Web的都知道,其實要麼在Web.xml裏面配置一個ContextLoaderListener,要麼配置一個自啓動的LoaderServlet.其實比較簡單了,我展現下ContextLoaderListener.
<!-- 加載spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
複製代碼
若是不是根據xml文件啓動Spring容器而是根據@Configuration類啓動,其實也很簡單.
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<!-- 加載spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.zdy.Configuration</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
複製代碼
配置一個contextClass參數ApplicationContext改成AnnotationConfigWebApplicationContext,而後contextConfigLocation不是指定配置文件xml位置了,改成指定Configuration類的位置。就OK了。
最後,須要強調的是,因爲Spring容器自帶的Log4j功能,因此用戶能夠直接將Log4j的配置文件放置在類路徑下,直接就生效了,可是,若是不在類路徑下,須要在Web.xml中手動指定文件的位置和啓動log4j的listener,這裏我就不演示了,須要注意的是,這個log4j的listener或者servlet必須在spring容器的listenier或servlet前面。不要問爲何。就是這麼規定的。不過這點你們不經常使用,因此我只是提一提。
好了,其實你們也看出來了,講Spring的時候我仍是偏向於使用的,Spring的底層深層次的原理其實設計到的很少。Spring這個至尊框架,我以爲先要宏觀使用上先整明白。後期有機會給你們多講點底層實現。喜歡你們多關注接下來的Spring系列文章。Over,Have a good day .