Spring是一個輕量級的IoC和AOP容器框架。是爲Java應用程序提供基礎性服務的一套框架,目的是用於簡化企業應用程序的開發,它使得開發者只須要關心業務需求。常見的配置方式有三種:基於XML的配置、基於註解的配置、基於Java的配置。java
主要由如下幾個模塊組成:web
Spring Core:核心容器,提供Spring框架的基本功能。核心容器的主要組件是BeanFactory,它是工廠模式的實現。BeanFactory 使用控制反轉(IOC)模式,將應用程序的配置和依賴性規範與實際的應用程序代碼分開。正則表達式
Beans模塊:提供了BeanFactory,是工廠模式的經典實現,Spring將管理對象稱爲Bean。spring
Core核心模塊:提供了Spring框架的基本組成部分,包括Ioc和Di.數據庫
Context:Spring上下文,是一個配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企業服務,例如 JNDI、EJB、電子郵件、國際化、校驗和調度功能。編程
Expression Language 模塊:是運行時查詢和操做對象圖的強大的表達式語言。緩存
Spring AOP:經過配置管理特性,Spring AOP 模塊直接將面向切面的編程功能集成到了 Spring 框架中。能夠很容易地使 Spring框架管理的任何對象支持AOP。Spring AOP模塊爲基於 Spring 的應用程序中的對象提供了事務管理服務。經過使用 Spring AOP,就能夠將聲明性事務管理集成到應用程序中。安全
Spring DAO:DBC DAO 抽象層提供了有意義的異常層次結構,可用該結構來管理異常處理和不一樣數據庫供應商拋出的錯誤消息。異常層次結構簡化了錯誤處理,而且極大地下降了須要編寫的異常代碼數量(例如打開和關閉鏈接)。Spring DAO 的面向 JDBC 的異常聽從通用的 DAO 異常層次結構。session
Spring ORM:Spring 框架插入了若干個 ORM 框架,從而提供了 ORM 的對象關係工具,其中包括JDO、Hibernate和iBatis SQL Map。全部這些都聽從 Spring 的通用事務和 DAO 異常層次結構。app
Spring Web:Web上下文模塊創建在應用程序上下文模塊之上,爲基於 Web 的應用程序提供了上下文。因此Spring 框架支持與 Jakarta Struts的集成。Web模塊還簡化了處理多部分請求以及將請求參數綁定到域對象的工做。
Spring MVC:MVC 框架是一個全功能的構建 Web 應用程序的 MVC 實現。經過策略接口,MVC 框架變成爲高度可配置的,MVC 容納了大量視圖技術,其中包括 JSP、Velocity、Tiles、iText 和 POI。
(1)spring屬於低侵入式設計,代碼的污染極低;
(2)spring的DI機制將對象之間的依賴關係交由框架處理,減低組件的耦合性;
(3)Spring提供了AOP技術,支持將一些通用任務,如安全、事務、日誌、權限等進行集中式管理,從而提供更好的複用。
(4)spring對於主流的應用框架提供了集成支持。
三、Spring框架核心組件
(1)BeanFactory
(2)ApplicationContext
(3)IOC控制反轉
(4)DI依賴注入
(5)AOP面向切面編程
所謂IoC,對於spring框架來講,就是由spring來負責控制對象的生命週期和對象間的關係。
IoC的一個重點是在系統運行中,動態的向某個對象提供它所須要的其餘對象。這一點是經過DI(Dependency Injection,依賴注入)來實現的.
DI注入的方式: setter 注入、構造器注入、註解注入。
1.IOC容器的概念:IoC容器就是具備依賴注入功能的容器,IoC容器負責實例化、定位、配置應用程序中的對象及創建這些對象間的依賴。應用程序無需直接在代碼中new相關的對象,應用程序由IoC容器進行組裝。在Spring中BeanFactory是IoC容器的實際表明者。
2.Bean的概念:由IoC容器管理的那些組成應用程序的對象咱們就叫它Bean, Bean就是由Spring容器初始化、裝配及管理的對象,除此以外,bean就與應用程序中的其餘對象沒有什麼區別了。
什麼是做用域呢?即「scope」,在面向對象程序設計中通常指對象或變量之間的可見範圍。而在Spring容器中是指其建立的Bean對象相對於其餘Bean對象的請求可見範圍。
基本的做用域:
1.singleton:指「singleton」做用域的Bean只會在每一個Spring IoC容器中存在一個實例,並且其完整生命週期徹底由Spring容器管理。對於全部獲取該Bean的操做Spring容器將只返回同一個Bean。
2.prototype:即原型,指每次向Spring容器請求獲取Bean都返回一個全新的Bean,相對於「singleton」來講就是不緩存Bean,每次都是一個根據Bean定義建立的全新Bean。
3.request:表示每一個請求須要容器建立一個全新Bean。好比提交表單的數據必須是對每次請求新建一個Bean來保持這些表單數據,請求結束釋放這些數據。
4.session:表示每一個會話須要容器建立一個全新Bean。好比對於每一個用戶通常會有一個會話,該用戶的用戶信息須要存儲到會話中,此時能夠將該Bean配置爲web做用域。
5.globalSession:相似於session做用域,只是其用於portlet環境的web應用。若是在非portlet環境將視爲session做用域。
1. 實例化一個Bean,也就是咱們一般說的new;
2. 按照Spring上下文對實例化的Bean進行配置,也就是DI依賴注入;
3. 若是這個Bean實現了BeanNameAware接口,會調用它實現的setBeanName(String beanId)方法,此處傳遞的是Spring配置文件中Bean的ID;
4. 若是這個Bean實現了BeanFactoryAware接口,會調用它實現的setBeanFactory(),傳遞的是Spring工廠自己(能夠用這個方法獲取到其餘Bean);
5. 若是這個Bean實現了ApplicationContextAware接口,會調用setApplicationContext(ApplicationContext)方法,傳入Spring上下文,該方式一樣能夠實現步驟4,但比4更好,覺得ApplicationContext是BeanFactory的子接口,有更多的實現方法;
6. 若是這個Bean關聯了BeanPostProcessor接口,將會調用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor常常被用做是Bean內容的更改,而且因爲這個是在Bean初始化結束時調用After方法,也可用於內存或緩存技術;
7. 若是這個Bean在Spring配置文件中配置了init-method屬性會自動調用其配置的初始化方法;
8. 若是這個Bean關聯了BeanPostProcessor接口,將會調用postAfterInitialization(Object obj, String s)方法;
注意:以上工做完成之後就能夠用這個Bean了,那這個Bean是一個single的,因此通常狀況下咱們調用同一個ID的Bean會是在內容地址相同的實例;
9. 當Bean再也不須要時,會通過清理階段,若是Bean實現了DisposableBean接口,會調用其實現的destroy方法;
10. 最後,若是這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷燬方法;
1、 @Value賦值和@propertySource加載外部配置文件
1.@Value 通常用在屬性和setter方法上,當該類註冊成bean時,會自動爲其屬性或方法的參數賦值。注意:必定不能用在靜態方法上,不然會失效
2.用法:
@Value("placeholder") //賦予指定值
@Value("${placeholder}") //賦予配置文件中指定key爲placeholder的值
3.@PropertySource("classpath:application.properties") //導入指定的配置文件,通常寫在主配置類上
二 、@Autowired和@Qualifier和@Primary
一、@Autowired(required=boolean) // 默認byType注入,若是找到多個相同類型的組件,再將屬性的名稱byName去注入,required設置是否必須注入,默認true,可用於屬性、方法、構造器、參數
二、@Qualifier("name") //與@Autowired搭配使用讓@Autowired變成byName去注入
三、@Primary //當多個bean是同一個類型時,@Autowired會首選@Primary 的bean去裝配
@Autowired和@Resource之間的區別:
(1) @Autowired默認是按照類型裝配注入的,默認狀況下它要求依賴對象必須存在(能夠設置它required屬性爲false)。
(2) @Resource默認是按照名稱來裝配注入的,只有當找不到與名稱匹配的bean纔會按照類型來裝配注入。
三 、@Resource和@Inject
一、@Resource(name="name") //能夠和@Autowired同樣實現自動注入功能,默認byName進行裝配;但不能支持 @Primary 和 @Autowired(required=false)
二、@Inject //須要導入javax.inject包纔有這個註解,和@Autowired功能同樣,可是沒有 @Autowired(required=false) 功能
4、自動裝配
在spring中,對象無需本身查找或建立與其關聯的其餘對象,由容器負責把須要相互協做的對象引用賦予各個對象,使用autowire來配置自動裝載模式。
在Spring框架xml配置中共有5種自動裝配:
(1)no:默認的方式是不進行自動裝配的,經過手工設置ref屬性來進行裝配bean。
(2)byName:經過bean的名稱進行自動裝配,若是一個bean的 property 與另外一bean 的name 相同,就進行自動裝配。
(3)byType:經過參數的數據類型進行自動裝配。
(4)constructor:利用構造函數進行裝配,而且構造函數的參數經過byType進行裝配。
(5)autodetect:自動探測,若是有構造方法,經過 construct的方式自動裝配,不然使用 byType的方式自動裝配。(1)Spring事務的種類:
spring支持編程式事務管理和聲明式事務管理兩種方式:
①編程式事務管理使用TransactionTemplate。
②聲明式事務管理創建在AOP之上的。其本質是經過AOP功能,對方法先後進行攔截,將事務處理的功能編織到攔截的方法中,也就是在目標方法開始以前加入一個事務,在執行完目標方法以後根據執行狀況提交或者回滾事務。
聲明式事務最大的優勢就是不須要在業務邏輯代碼中摻瑣事務管理的代碼,只需在配置文件中作相關的事務規則聲明或經過@Transactional註解的方式,即可以將事務規則應用到業務邏輯中。
@Transactional(timeout = 30, readOnly = false, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
1. timeout 事務的超時時間,默認值爲-1,表示沒有超時顯示。若是配置了具體時間,則超過該時間限制但事務尚未完成,則自動回滾事務。
2.read-only 指定事務是否爲只讀事務,默認值爲 false;爲了忽略那些不須要事務的方法,好比讀取數據,能夠設置 read-only 爲 true。
3. rollback-for 用於指定可以觸發事務回滾的異常類型,若是有多個異常類型須要指定,各種型之間能夠經過逗號分隔。
4.no-rollback- for 拋出 no-rollback-for 指定的異常類型,不回滾事務。
5.isolation 事務的隔離度,默認值採用 DEFAULT。
聲明式事務管理要優於編程式事務管理,這正是spring倡導的非侵入式的開發方式,使業務代碼不受污染,只要加上註解就能夠得到徹底的事務支持。惟一不足地方是,最細粒度只能做用到方法級別,沒法作到像編程式事務那樣能夠做用到代碼塊級別。
(2)spring的事務傳播行爲:
事務傳播(Propagation)特性是指不一樣業務(service)對象中的事務方法之間相互調用時,事務的傳播方式。
① PROPAGATION_REQUIRED:若是當前沒有事務,就建立一個新事務,若是當前存在事務,就加入該事務,該設置是最經常使用的設置。(默認)
② PROPAGATION_SUPPORTS:支持當前事務,若是當前存在事務,就加入該事務,若是當前不存在事務,就以非事務執行。‘
③ PROPAGATION_MANDATORY:支持當前事務,若是當前存在事務,就加入該事務,若是當前不存在事務,就拋出異常。
④ PROPAGATION_REQUIRES_NEW:建立新事務,不管當前存不存在事務,都建立新事務。
⑤ PROPAGATION_NOT_SUPPORTED:以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
⑥ PROPAGATION_NEVER:以非事務方式執行,若是當前存在事務,則拋出異常。
⑦ PROPAGATION_NESTED:若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則按REQUIRED屬性執行。
(3)Spring中的隔離級別:
① ISOLATION_DEFAULT:這是個 PlatfromTransactionManager 默認的隔離級別,使用數據庫默認的事務隔離級別。
② ISOLATION_READ_UNCOMMITTED:讀未提交,容許另一個事務能夠看到這個事務未提交的數據。
③ ISOLATION_READ_COMMITTED:讀已提交,保證一個事務修改的數據提交後才能被另外一事務讀取,並且能看到該事務對已有記錄的更新。
④ ISOLATION_REPEATABLE_READ:可重複讀,保證一個事務修改的數據提交後才能被另外一事務讀取,可是不能看到該事務對已有記錄的更新。
⑤ ISOLATION_SERIALIZABLE:一個事務在執行的過程當中徹底看不到其餘事務對數據庫所作的更新。
AOP,通常稱爲面向切面,做爲面向對象的一種補充,用於將那些與業務無關,但卻對多個對象產生影響的公共行爲和邏輯,抽取並封裝爲一個可重用的模塊,這個模塊被命名爲「切面」(Aspect),減小系統中的重複代碼,下降了模塊間的耦合度,同時提升了系統的可維護性。可用於權限認證、日誌、事務處理。
AOP實現的關鍵在於 代理模式,AOP代理主要分爲靜態代理和動態代理。靜態代理的表明爲AspectJ;動態代理則以Spring AOP爲表明。
(1)AspectJ是靜態代理的加強,所謂靜態代理,就是AOP框架會在編譯階段生成AOP代理類,所以也稱爲編譯時加強,他會在編譯階段將AspectJ(切面)織入到Java字節碼中,運行的時候就是加強以後的AOP對象。
(2)Spring AOP使用的動態代理,所謂的動態代理就是說AOP框架不會去修改字節碼,而是每次運行時在內存中臨時爲方法生成一個AOP對象,這個AOP對象包含了目標對象的所有方法,而且在特定的切點作了加強處理,並回調原對象的方法。
Spring AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理:
①JDK動態代理只提供接口的代理,不支持類的代理。核心InvocationHandler接口和Proxy類,InvocationHandler 經過invoke()方法反射來調用目標類中的代碼,動態地將橫切邏輯和業務編織在一塊兒;接着,Proxy利用 InvocationHandler動態建立一個符合某一接口的的實例, 生成目標類的代理對象。
②若是代理類沒有實現 InvocationHandler 接口,那麼Spring AOP會選擇使用CGLIB來動態代理目標類。CGLIB(Code Generation Library),是一個代碼生成的類庫,能夠在運行時動態的生成指定類的一個子類對象,並覆蓋其中特定方法並添加加強代碼,從而實現AOP。CGLIB是經過繼承的方式作的動態代理,所以若是某個類被標記爲final,那麼它是沒法使用CGLIB作動態代理的。
(3)靜態代理與動態代理區別在於生成AOP代理對象的時機不一樣,相對來講AspectJ的靜態代理方式具備更好的性能,可是AspectJ須要特定的編譯器進行處理,而Spring AOP則無需特定的編譯器處理。
在AOP中,經過切入點選擇目標對象的鏈接點,而後在目標對象的相應鏈接點處織入通知,而切入點和通知就是切面(橫切關注點),而在目標對象鏈接點處應用切面的實現方式是經過AOP代理對象;
切入點指示符用來指示切入點表達式目的,,在Spring AOP中目前只有執行方法這一個鏈接點,Spring AOP支持的AspectJ切入點指示符以下:
execution:用於匹配方法執行的鏈接點;
within:用於匹配指定類型內的方法執行;
this:用於匹配當前AOP代理對象類型的執行方法;注意是AOP代理對象的類型匹配,這樣就可能包括引入接口也類型匹配;
target:用於匹配當前目標對象類型的執行方法;注意是目標對象的類型匹配,這樣就不包括引入接口也類型匹配;
args:用於匹配當前執行的方法傳入的參數爲指定類型的執行方法;
@within:用於匹配因此持有指定註解類型內的方法;
@target:用於匹配當前目標對象類型的執行方法,其中目標對象持有指定的註解;
@args:用於匹配當前執行的方法傳入的參數持有指定註解的執行;
@annotation:用於匹配當前執行方法持有指定註解的方法;
bean:Spring AOP擴展的,AspectJ沒有對於指示符,用於匹配特定名稱的Bean對象的執行方法;
reference pointcut:表示引用其餘命名切入點,只有@ApectJ風格支持,Schema風格不支持。