專題一
(1)Spring Framework Runtime

Test模塊支持使用JUnit和TestNG對(duì)Spring組件進(jìn)行測試。Core Container(核心容器)包含有Beans、Core、Context和SpEL模塊。AOP模塊提供了一個(gè)符合AOP聯(lián)盟標(biāo)準(zhǔn)的面向切面編程的實(shí)現(xiàn)。Data Access/Integration層包含有JDBC、ORM、OXM、JMS和Transaction模塊。Web層包含了Web、Web-Servlet、WebSocket、Web-Porlet模塊。
(2)輕量級(jí)JavaEE VS 重量級(jí)(傳統(tǒng))JavaEE兩層含義:
1,輕量級(jí)是相對(duì)于重量級(jí)而言的,輕量級(jí)一般就是非入侵性的、所依賴的東西非常少、資源占用非常少、部署簡單等等,其實(shí)就是比較容易使用,而重量級(jí)正好相反。
2,相比較傳統(tǒng)的JavaEE項(xiàng)目,即真正意義上的JavaEE規(guī)范(比如EJB3.0;JPA;JMX;JMS;JNDI;JSF等),我們把能直接在Tomcat等符合JavaServlet規(guī)范的Web服務(wù)器上能直接運(yùn)行的Java應(yīng)用稱為輕量級(jí)的JavaEE應(yīng)用;一般就意味著以Spring為代表的一些事實(shí)上的標(biāo)準(zhǔn)開發(fā)框架;可以說,Spring就是運(yùn)行在Web服務(wù)器中的ApplicationServer;
(3)Spring的系列產(chǎn)品;Spring Boot:為基于Spring的應(yīng)用開發(fā)提供了基礎(chǔ)的項(xiàng)目構(gòu)建;Spring Data:用于簡化數(shù)據(jù)庫訪問,并支持云服務(wù)的開源框架。旨在統(tǒng)一和簡化對(duì)各類型持久化存儲(chǔ), 而不拘泥是關(guān)系型數(shù)據(jù)庫還是NoSQL數(shù)據(jù)存儲(chǔ)。Spring Batch:專門針對(duì)企業(yè)級(jí)系統(tǒng)中的日常批處理任務(wù)的輕量級(jí)框架,能夠幫助開發(fā)者方便地開發(fā)出強(qiáng)壯、高效的批處理應(yīng)用程序。Spring Integration:為Spring編程模型提供了一個(gè)支持企業(yè)集成模式(Enterprise Integration Patterns)的擴(kuò)展,在應(yīng)用程序中提供輕量級(jí)的消息機(jī)制,可以通過聲明式的適配器與外部系統(tǒng)進(jìn)行集成。Spring Security:早期稱為Acegi,基于Spring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問控制解決方案的安全框架;。Spring Roo:快速應(yīng)用程序開發(fā)工具,可以在短時(shí)間內(nèi)方便地構(gòu)建應(yīng)用程序。Spring Mobile:對(duì)Spring MVC的擴(kuò)展,旨在簡化移動(dòng)Web應(yīng)用的開發(fā)。Spring for Android:用于簡化Android原生應(yīng)用程序開發(fā)的Spring擴(kuò)展。
(4)Spring的版本
Spring2.5:
¨擁抱驅(qū)動(dòng)編程。
支持SimpleJdbcTemplate的命名參數(shù)操作。
Spring3.x:
不再支持JDK1.4;
¨全面支持泛型。
支持SpEL.
支持WebService的OXM。
Spring4.x:
支持Java8,支持JavaEE6規(guī)范。
泛型限定式依賴注入。
對(duì)Hibernate4的集成和事務(wù)提供更好的管理方案。
(5)IOC的概念
IoC:inverseof control,即控制反轉(zhuǎn);
簡單的說,就是把對(duì)象的實(shí)例化工作交給容器來完成;
遇到的問題:
1,業(yè)務(wù)代碼都使用接口,按照接口編程,能夠解除耦合;
2,使用傳統(tǒng)的開發(fā)方式,雖然在業(yè)務(wù)聲明,業(yè)務(wù)代表調(diào)用上確實(shí)使用的是接口,但是這個(gè)業(yè)務(wù)類的實(shí)體需要客戶端自己去初始化,初始化一定是某一個(gè)具體的接口實(shí)現(xiàn)類,所以,并沒有做到完全的解耦;
A和B兩個(gè)類,A類使用到B類,A類就要負(fù)責(zé)B類的實(shí)例化過程,
怎么做?A類依賴B類,A類不要直接去實(shí)例化B類,而是把實(shí)例化B類的過程交給容器,A類只需要從容器中取得初始化的實(shí)例化對(duì)象;
(6)基于Spring的HelloWorld:
1,基礎(chǔ)代碼(接口+實(shí)現(xiàn));
2,拷貝core.jar和beans.jar
3,告訴spring要管理的bean--->配置文件(在spring中配置文件一般命名為application.xml或者appliactionContext.xml)

4,測試:

在HelloWorld實(shí)例中,注意:
1,從容器中拿對(duì)象,使用的是接口拿(這樣才能真正做到解耦);
2,研究從Spring中拿Bean的原理:
1,先從classpath下加載Spring的配置文件;
2,使用配置文件創(chuàng)建一個(gè)BeanFactory對(duì)象;
1,遍歷配置文件中所有的bean元素;
2,根據(jù)bean元素的class屬性去創(chuàng)建一個(gè)對(duì)象的實(shí)例(Class.forName(“class”)).newInstance();
3,把創(chuàng)建好的實(shí)例+bean元素中的id存放到容器中;
3,使用getBean方法的時(shí)候,就是按照查詢(getBean)的方式,從容器中找到合適的bean的實(shí)例并返回;
** ****結(jié)論:**
1,默認(rèn)情況下,交給Spring管理的bean必須有一個(gè)默認(rèn)的構(gòu)造方法;
2,在Spring中,配置的每一個(gè)bean其實(shí)是一個(gè)實(shí)例;
3,根據(jù)配置的class,調(diào)用的是Class.forName(“class”)).newInstance()---->newClass....
所以,Spring其實(shí)就是把本來應(yīng)該寫在代碼中的初始化代表移動(dòng)到XML中了;
(7)Spring中bean的名稱:
1,Spring中的模塊管理:
在Spring中,如果大量的類都配置在一個(gè)配置文件中,難以管理,可以按照模塊,把bean配置在不同的XML中,并使用主的配置文件來引入這些模塊的配置文件;

2,Spring中的bean的名稱:

(8)Spring中的測試:
之前的測試存在的問題:
1,每一個(gè)測試方法,都需要手動(dòng)啟動(dòng)Spring;相當(dāng)于Spring容器是運(yùn)行在測試類的方法中的;
2,每一個(gè)測試方法,都需要手動(dòng)啟動(dòng)Spring,還需要正常的關(guān)閉Spring;
3,各個(gè)模塊的配置文件混淆在一起;
Spring中的測試,不僅僅是提供了更好的測試方式,在Spring的測試包中,還包括了很多Mock對(duì)象,還有用于事務(wù)控制的測試或者集成測試等很多輔助的測試工具;

步驟:
1,拷包(替換默認(rèn)的eclipse的JUNIT環(huán)境;拷貝context.jar,expression.jar,aop.jar)
2,在類上使用@RunWith
3,在類上使用@ContextConfiguration;
4,在類中使用@Autowire標(biāo)簽放在BeanFactory屬性上;
5,在測試代碼中,只需要直接從BeanFactory獲取bean即可;
(9)容器:
1,Spring中最簡單的,最基礎(chǔ)的容器 BeanFactory;
在BeanFactory中,提供了一些最基本的容器的方法;最重要的就是提供了從容器中拿對(duì)象的方法;
因?yàn)锽eanFactory提供的功能太簡單了,所以平時(shí)開發(fā)時(shí)很少使用;
2,Spring中最常用的容器:ApplicationContext
1,ApplicationContext繼承了BeanFactory接口,所以,ApplicationContext也提供了最基本的拿bean的方法;
2,ApplicationContext在BeanFactory的基礎(chǔ)之上,提供了更多的應(yīng)用所需的功能:
1,容器環(huán)境的感知;
2,bean的繼承;
3,國際化;
4,Spring的事件機(jī)制;
5,統(tǒng)一的資源處理;
6,AOP;
3,ApplicationContext的使用:
1,在Springtest中的使用(在使用Spring-test的時(shí)候,啟動(dòng)的本來就是ApplicationContext容器):

2,手動(dòng)創(chuàng)建ApplicationContext容器;

(10)Spring中在不同容器下,bean的初始化時(shí)機(jī);1,BeanFactory是在真正去拿bean的時(shí)候,才會(huì)去創(chuàng)建bean的實(shí)例(延遲實(shí)例化);
2,ApplicationContext是在容器啟動(dòng)的時(shí)候就已經(jīng)創(chuàng)建好了bean的實(shí)例(迫切實(shí)例化);
延遲實(shí)例化的優(yōu)勢:應(yīng)用啟動(dòng)的時(shí)候占用的資源很小;適合資源緊張的應(yīng)用;
迫切實(shí)例化的優(yōu)勢:應(yīng)用在啟動(dòng)的時(shí)候已經(jīng)實(shí)例化所有的對(duì)象,就可以在啟動(dòng)的時(shí)候發(fā)現(xiàn)對(duì)象的錯(cuò)誤或者為這些對(duì)象做更多的事情(比如AOP);
建議Web應(yīng)用中,就使用迫切加載;
當(dāng)然,也可以在bean上面添加lazy-init=true來讓ApplicationContext也延遲實(shí)例化對(duì)象;
還可以在beans上面配置default-lazy-init=true讓整個(gè)beans中所有的bean全部延遲實(shí)例化;
(11)Spring中bean的實(shí)例化方式:bean是怎么創(chuàng)建出來的.
1,bean使用默認(rèn)的構(gòu)造方法創(chuàng)建:

2,靜態(tài)工廠方法;

配置文件:

拿bean:

3,實(shí)例工廠方法:

配置文件:

拿bean:

4,Spring內(nèi)置的工廠類;
1,創(chuàng)建一個(gè)工廠類,實(shí)現(xiàn)FactoryBean接口;

2,配置:

3,獲取bean:

(12):spring處理factorybean的過程:
1,先從classpath下加載Spring的配置文件;
2,使用配置文件創(chuàng)建一個(gè)ApplicationContext對(duì)象;
1,遍歷配置文件中所有的bean元素;
2,根據(jù)bean元素的class屬性去創(chuàng)建一個(gè)對(duì)象的實(shí)例(Class.forName(“class”)).newInstance();
3,判斷當(dāng)前創(chuàng)建的對(duì)象是否是一個(gè)FactoryBean的實(shí)例;
3.1如果不是,繼續(xù)向下執(zhí)行
3.2是一個(gè)FactoryBean接口;
1,先把這個(gè)實(shí)例+&id存放到容器中;
2,FactoryBean bean=(FactoryBean)instance;
然后調(diào)用bean.getObject()創(chuàng)建一個(gè)實(shí)例,然后再把這個(gè)實(shí)例+id存放到容器中;
3,把創(chuàng)建好的實(shí)例+bean元素中的id存放到容器中;
3,使用getBean方法的時(shí)候,就是按照查詢(getBean)的方式,從容器中找到合適的bean的實(shí)例并返回;
4,總結(jié):如果一個(gè)類繼承了Spring中提供的內(nèi)部的某一個(gè)接口,當(dāng)我把這個(gè)類配置在Spring容器中,這個(gè)類就有了一些Spring特殊的功能;
(13)****Bean的Scope:1,默認(rèn)情況下,Spring中的bean都是單例的;
2,可以通過bean的scope屬性來配置對(duì)象的生命周期范圍
1,default/singleton:默認(rèn)的配置,代表bean是單例的
2,prototype:
把scope設(shè)置為prototpe,每次得到的對(duì)象都是一個(gè)全新的對(duì)象;
prototype類型的bean,在容器啟動(dòng)的時(shí)候不會(huì)創(chuàng)建,只會(huì)在每次從容器拿對(duì)象的時(shí)候,才會(huì)創(chuàng)建;
3,request:在一次請(qǐng)求中創(chuàng)建一個(gè)對(duì)象,必須依賴HTTP環(huán)境
session:在一次會(huì)話中創(chuàng)建一個(gè)對(duì)象,必須依賴HTTP環(huán)境
3,什么時(shí)候使用prototype?線程不安全的對(duì)象交給Spring管理,就必須設(shè)置為prototype,比如struts2的Action;
(14)Bean的初始化方法和銷毀方法:1,有的時(shí)候,在bean初始化完成之后,還要調(diào)用一些初始化方法才能讓bean處于立刻可用狀態(tài);
2,有的時(shí)候,在spring正常關(guān)閉,銷毀bean的時(shí)候,需要調(diào)用bean的一些銷毀方法來正常釋放資源;
3,可以通過bean上面的init-method和destory-method來配置

4,注意,init-method和dstory-method都不能有參數(shù);
5,如何手動(dòng)正常關(guān)閉Spring容器?
a:

b:

6,多例的對(duì)象是不會(huì)調(diào)用destory-method的;
(14)IOC容器

(15)什么叫DI(Dependence inject),依賴注入
對(duì)象的屬性關(guān)系由spring來管理;對(duì)象的屬性由Spring來設(shè)置;
兩種注入方式:
1,使用Setter注入(使用屬性的對(duì)應(yīng)的setter方法來注入,要求set方法);
2,使用構(gòu)造器注入
(16)使用setter注入:
1,簡單類型;

2,某一些復(fù)雜類型;


1,從spring配置文件中得到的值(value能夠配置的值)都是String類型的,但是針對(duì)某些類型,Spring內(nèi)部可以直接把String類型轉(zhuǎn)化對(duì)應(yīng)的類型;
2,Spring的轉(zhuǎn)型依賴PropertyEditor;
3,其他的bean;

4,集合; 1,list 2,set 3,map 4,properties 集合注入在一般情況下面不會(huì)使用,一般是一些框架相關(guān)的bean才會(huì)使用到;
(17)構(gòu)造方法注入:
1,如果在bean中沒有配置constructor-arg參數(shù),則spring會(huì)使用對(duì)象默認(rèn)的無參構(gòu)造方法實(shí)例化對(duì)象;
2,如果在bean中配置了constructor-arg參數(shù),spring會(huì)使用這些constructor-arg去唯一確定一個(gè)構(gòu)造方法,并使用這個(gè)構(gòu)造方法創(chuàng)建對(duì)象實(shí)例;
確定構(gòu)造方法?
1,默認(rèn)情況下,constructor-arg的順序就是構(gòu)造方法參數(shù)的順序(在實(shí)際使用中,推薦就按照默認(rèn)的方式來設(shè)置值即可);
2,三種方式可以調(diào)整構(gòu)造方法參數(shù)的順序:
1,index:通過構(gòu)造方法參數(shù)位置來指定;從0開始;
2,type:在構(gòu)造方法中參數(shù)的類型;
3,name:使用構(gòu)造方法參數(shù)的名字來設(shè)置;
(18)setter VS 構(gòu)造方法注入
1,使用setter和構(gòu)造方法都能夠正確的注入bean的屬性;
2,構(gòu)造方法可以更強(qiáng)制的規(guī)定依賴的對(duì)象必須存在,如果不配置,則創(chuàng)建對(duì)象失?。坏菢?gòu)造方法不宜有過多的參數(shù),否則代碼難以維護(hù);
3,更多的還是使用setter方式的注入,但是setter注入可能會(huì)產(chǎn)生忘記配置的問題,可以使用@Required注解來配置;