一、輕量級、非侵入式的框架;對現有的類結構沒有影響
二、能夠提供衆多服務,如事務管理、WS(WebService)等
三、AOP很好支持、方便麪向切面編程、將業務邏輯和系統服務分開
四、對主流的框架提供了很好的集成支持,如hibernate、Struts二、JPA等,像一個膠水同樣,把一些好的框架粘合在一塊兒方便使用
五、使用Spring的IOC容器,將對象之間的依賴關係交給Spring,下降組件之間的耦合性,讓咱們更專一於應用邏輯代碼
六、Spring DI機制下降了業務對象替換的複雜性。
七、Spring的高度可開放性,並不強制依賴於Spring,開發者能夠自由選擇Spring部分或所有
複製代碼
一、缺乏一個公用控制器
二、沒有SpringBoot好用
三、Spring像一個膠水,將框架黏在一塊兒,後面拆分的話就不容易拆分了
複製代碼
依賴注入(Dependecy Injection)和控制反轉(Inversion of Control)是同一個概念,具體的講:當某個角色須要另一個角色協助的時候,在傳統的程序設計過程當中,一般由調用者來建立被調用者的實例。但在spring中建立被調用者的工做再也不由調用者來完成,所以稱爲控制反轉。建立被調用者的工做由spring來完成,而後注入調用者所以也稱爲依賴注入
複製代碼
一、核心業務功能和切面功能分別獨立進行開發 ,而後把切面功能和核心業務功能 "編織" 在一塊兒,這就叫AOP
二、讓關注點代碼與業務代碼分離(各個步驟之間良好的隔離性、源代碼無關性)
三、面向切面編程就是指: 對不少功能都有的重複的代碼抽取,再在運行的時候往業務方法上動態植入「切面類代碼」。
四、應用場景:日誌,事務管理,權限控制
複製代碼
主要經過Proxy.newProxyInstance()和InvocationHandler這兩個類和方法實現spring
cglib數據庫
生成對象類型爲Enhancer編程
實現原理相似於 jdk 動態代理,只是他在運行期間生成的代理對象是針對目標類擴展的子類緩存
靜態代理markdown
在編譯的時候就直接生成代理類session
缺點:若是要代理一個接口的多個實現的話須要定義不一樣的代理類 代理類 和 被代理類 必須實現一樣的接口,萬一接口有變更,代理、被代理類都得修改數據結構
jdk和cglib的對比框架
XML方式maven
註解方式學習
基於JAVA類配置
經過 @Configuration 和 @Bean 這兩個註解實現的
@Configuration 做用於類上,至關於一個xml配置文件;
@Bean 做用於方法上,至關於xml配置中的bean;
裝配方式(依賴注入的具體行爲)
i、基於註解的自動裝配
註解:
@Autowired(byType)+@Qualifier
@Resource(byName)
自動掃描:
component-scan
ii、基於XML配置的顯式裝配
iii、基於Java配置的顯式裝配
能在編譯時就發現錯誤
依賴注入的方式
i、構造器方式注入
構造器依賴注入經過容器觸發一個類的構造器來實現的,該類有一系列參數,每一個參數表明一個對其餘類的依賴。
例如:<bean id="hello" class="com.maven.Hello"><property name="text" ref="text" /></bean>
複製代碼
ii、settter方法注入
之因此叫setter方法注入,由於這是經過找到類的對應的setter方法,再進行相應的注入
Setter方法注入是容器經過調用無參構造器或無參static工廠 方法實例化bean以後,調用該bean的setter方法,即實現了基於setter的依賴注入。
iii、最好的解決方案是
用構造器參數實現強制依賴,setter方法實現可選依賴
循環依賴 i、構造器方式沒法解決,只能拋出異常
ii、多例方式沒法解決,只能拋出異常
由於Spring容器不緩存"prototype"做用域的bean,所以沒法提早暴露一個建立中的bean。
iii、單例模式能夠解決
經過提早暴露一個單例工廠方法,從而使其餘bean可以引用到該bean提早暴露一個正在建立中的bean
iiii、不用建立對象,而只須要描述它如何被建立,不在代碼裏直接組裝組件和服務,可是要在配置文件裏描述哪些組件須要哪些服務,以後一個容器(IOC容器)負責把他們組裝起來。
1.Resource定位;指對BeanDefinition的資源定位過程。通俗地講,就是找到定義Javabean信息的XML文件,並將其封裝成Resource對象。
2.BeanDefinition的載入;把用戶定義好的Javabean表示爲IoC容器內部的數據結構,這個容器內部的數據結構就是BeanDefinition。
3.向IoC容器註冊這些 BeanDefinition。
2. bean的做用域
1). singleton
singleton是Bean的默認做用域
默認狀況下是容器初始化的時候建立,但也可設定運行時再初始化bean
DefaultSingletonBeanRegistry類裏的singletonObjects哈希表保存了單例對象。
Spring IoC容器中只會存在一個共享的Bean實例,不管有多少個Bean引用它,始終指向同一對象。
Spring容器能夠管理singleton做用域下bean的生命週期,在此做用域下,Spring可以精確地知道bean什麼時候被建立,什麼時候初始化完成,以及什麼時候被銷燬
複製代碼
2). prototype
每次經過Spring容器獲取prototype定義的bean時,容器都將建立一個新的Bean實例,每一個Bean實例都有本身的屬性和狀態
當容器建立了bean的實例後,bean的實例就交給了客戶端的代碼管理,Spring容器將再也不跟蹤其生命週期,而且不會管理那些被配置成prototype做用域的bean的生命週期。
對有狀態的bean使用prototype做用域,而對無狀態的bean使用singleton做用域。
複製代碼
3). request
在一次Http請求中,容器會返回該Bean的同一實例。而對不一樣的Http請求則會產生新的Bean,並且該bean僅在當前Http Request內有效。
複製代碼
4). session
在一次Http Session中,容器會返回該Bean的同一實例。而對不一樣的Session請求則會建立新的實例,該bean實例僅在當前Session內有效。
複製代碼
5). global Session
在一個全局的Http Session中,容器會返回該Bean的同一個實例,僅在使用portlet context時有效。
複製代碼
bean的建立
1.進入getBean()方法
2.判斷當前bean的做用域是不是單例,若是是,則去對應緩存中查找,沒有查找到的話則新建實例並保存。若是不是單例,則直接新建實例(createBeanInstance)
3.新建實例後再將注入屬性(populateBean),並處理回調
1).建立bean
2).找到@Autowired的對象
3).建立注入對象,並賦值
複製代碼
若是須要某一組操做具備原子性,就用註解的方式開啓事務,按照給定的事務規則來執行提交或者回滾操做
事務管理通常在Service層
編程式事務控制(用戶經過代碼的形式手動控制事務)
1).Conn.setAutoCommite(false); // 設置手動控制事務
2).粒度較細,比較靈活,但開發起來比較繁瑣: 每次都要開啓、提交、回滾
複製代碼
聲明式事務控制(Spring提供對事物的控制管理)
1).XML方式
2).註解方式
複製代碼
事務傳播行爲
required_new:若是當前方法有事務了,當前方法事務會掛起,在爲加入的方法開啓一個新的事務,直到新的事務執行完、當前方法的事務纔開始
required(默認方法):若是當前方法已經有事務了,加入當前方法事務
其他五種方式(拓展學習)
事務傳播行爲用來描述由某一個事務傳播行爲修飾的方法被嵌套進另外一個方法的時候事務如何傳播。
數據庫的隔離級別(參考隔離級別的那篇文章)
事務超時屬性
指一個事務所容許執行的最長時間,若是超過該時間限制但事務尚未完成,則自動回滾事務。
事務只讀屬性
對事物資源是否執行只讀操做
回滾規則
定義了哪些異常會致使事務回滾而哪些不會。默認狀況下,事務只有遇到運行期異常時纔會回滾,而在遇到檢查型異常時不會回滾,也能夠用用戶本身定義
PlatformTransactionManager
TransactionDefinition
TransactionStatus
若是在dao層,回滾的時候只能回滾到當前方法,但通常咱們的service層的方法都是由不少dao層的方法組成的
若是在dao層,commit的次數會過多
1.加載和實例化
2.初始化
3.請求處理
4.服務終止