Spring七大模塊
Spring Core:框架的最基礎部分,提供 IoC 容器,對 bean 進行管理,它主要的組件就是BeanFactory, 是工廠模式的實作,同時BeanFactory適用控制反轉(IOC)思想將應用程式的配置和依賴性規范與實際的應用程式分開,
Spring Context:繼承BeanFactory,提供背景關系資訊,擴展出JNDI、EJB、電子郵件、國際化等功能,
Spring DAO:提供了JDBC的抽象層,還提供了宣告性事務管理方法,并且極大地降低了需要撰寫地例外代碼資料 (例如打開和關閉連接),
Spring ORM:提供了JPA、JDO、Hibernate、MyBatis 等ORM映射層.
Spring AOP:集成了所有AOP功能,減弱代碼的功能耦合,清晰的被分離開,
Spring Web:提供了基礎的 Web 開發的背景關系資訊,現有的Web框架,如JSF、Tapestry、Structs等,提供了集成
Spring Web MVC:提供了 Web 應用的 Model-View-Controller 全功能實作,
Bean定義5種作用域
singleton(單例) prototype(原型) request session global session
pring ioc初始化流程?
resource定位 即尋找用戶定義的bean資源,由 ResourceLoader通過統一的介面Resource介面來完成 beanDefinition載入 BeanDefinitionReader讀取、決議Resource定位的資源 成BeanDefinition 載入到ioc中(通過HashMap進行維護BD) BeanDefinition注冊 即向IOC容器注冊這些BeanDefinition, 通過BeanDefinitionRegistery實作
BeanDefinition加載流程?
定義BeanDefinitionReader決議xml的document BeanDefinitionDocumentReader決議document成beanDefinition
DI依賴注入流程? (實體化,處理Bean之間的依賴關系)
程序在Ioc初始化后,依賴注入的程序是用戶第一次向IoC容器索要Bean時觸發
如果設定lazy-init=true,會在第一次getBean的時候才初始化bean, lazy-init=false,會容器啟動的時候直接初始化(singleton bean);
呼叫BeanFactory.getBean()生成bean的;
生成bean程序運用裝飾器模式產生的bean都是beanWrapper(bean的增強);
依賴注入怎么處理bean之間的依賴關系?
其實就是通過在beanDefinition載入時,如果bean有依賴關系,通過占位符來代替,在呼叫getbean時候,如果遇到占位符,從ioc里獲取bean注入到本實體來
Bean的生命周期?
- 實體化Bean: Ioc容器通過獲取BeanDefinition物件中的資訊進行實體化,實體化物件被包裝在BeanWrapper物件中
- 設定物件屬性(DI):通過BeanWrapper提供的設定屬性的介面完成屬性依賴注入;
- 注入Aware介面(BeanFactoryAware, 可以用這個方式來獲取其它 Bean,ApplicationContextAware):Spring會檢測該物件是否實作了xxxAware介面,并將相關的xxxAware實體注入給bean
- BeanPostProcessor:自定義的處理(分前置處理和后置處理)
- InitializingBean和init-method:執行我們自己定義的初始化方法
- 使用
- destroy:bean的銷毀
IOC:控制反轉:將物件的創建權,由Spring管理. DI(依賴注入):在Spring創建物件的程序中,把物件依賴的屬性注入到類中,
Spring的IOC注入方式有哪幾種
構造器注入 setter方法注入 注解注入 介面注入
怎么檢測是否存在回圈依賴?
Bean在創建的時候可以給該Bean打標,如果遞回呼叫回來發現正在創建中的話,即說明了回圈依賴了,
Spring如解決Bean回圈依賴問題?
Spring中回圈依賴場景有:
- 構造器的回圈依賴
- 屬性的回圈依賴
- singletonObjects:第一級快取,里面放置的是實體化好的單例物件; earlySingletonObjects:第二級快取,里面存放的是提前曝光的單例物件; singletonFactories:第三級快取,里面存放的是要被實體化的物件的物件工廠
- 創建bean的時候Spring首先從一級快取singletonObjects中獲取,如果獲取不到,并且物件正在創建中,就再從二級快取earlySingletonObjects中獲取,如果還是獲取不到就從三級快取singletonFactories中取(Bean呼叫建構式進行實體化后,即使屬性還未填充,就可以通過三級快取向外提前暴露依賴的參考值(提前曝光),根據物件參考能定位到堆中的物件,其原理是基于Java的參考傳遞),取到后從三級快取移動到了二級快取完全初始化之后將自己放入到一級快取中供其他使用,
- 因為加入singletonFactories三級快取的前提是執行了構造器,所以構造器的回圈依賴沒法解決,
- 構造器回圈依賴解決辦法:在建構式中使用@Lazy注解延遲加載,在注入依賴時,先注入代理物件,當首次使用時再創建物件說明:一種互斥的關系而非層次遞進的關系,故稱為三個Map而非三級快取的緣由 完成注入;
Spring 中使用了哪些設計模式?
工廠模式: spring中的BeanFactory就是簡單工廠模式的體現,根據傳入唯一的標識來獲得bean物件;
單例模式: 提供了全域的訪問點BeanFactory;
代理模式: AOP功能的原理就使用代理模式(1、JDK動態代理,2、CGLib位元組碼生成技術代理,)
裝飾器模式: 依賴注入就需要使用BeanWrapper;
觀察者模式: spring中Observer模式常用的地方是listener的實作,如ApplicationListener,
策略模式: Bean的實體化的時候決定采用何種方式初始化bean實體(反射或者CGLIB動態位元組碼生成)
AOP 核心概念
1.切面(aspect):類是對物體特征的抽象,切面就是對橫切關注點的抽象
2.橫切關注點:對哪些方法進行攔截,攔截后怎么處理,這些關注點稱之為橫切關注點,
3.連接點(joinpoint):被攔截到的點,因為 Spring 只支持方法型別的連接點,所以在Spring 中連接點指的就是被攔截到的方法,實際上連接點還可以是欄位或者構造器,
4.切入點(pointcut):對連接點進行攔截的定義
5.通知(advice):所謂通知指的就是指攔截到連接點之后要執行的代碼,通知分為前置、后置、例外、最終、環繞通知五類,
6.目標物件:代理的目標物件
7.織入(weave):將切面應用到目標物件并導致代理物件創建的程序
8.引入(introduction):在不修改代碼的前提下,引入可以在運行期為類動態地添加方法或欄位,
解釋一下AOP
傳統oop開發代碼邏輯自上而下的,這個過程中會產生一些橫切性問題,這些問題與我們主業務邏輯關系不大,會散落在代碼的各個地方,造成難以維護,aop思想就是把業務邏輯與橫切的問題進行分離,達到解耦的目的,提高代碼重用性和開發效率;
AOP 主要應用場景有:
- 記錄日志
- 監控性能
- 權限控制
- 事務管理
- 執行緒池關閉等
AOP原始碼分析
- @EnableAspectJAutoProxy給容器(beanFactory)中注冊一個AnnotationAwareAspectJAutoProxyCreator物件;
- AnnotationAwareAspectJAutoProxyCreator對目標物件進行代理物件的創建,物件內部,是封裝JDK和CGlib兩個技術,實作動態代理物件創建的(創建代理物件程序中,會先創建一個代理工廠,獲取到所有的增強器(通知方法),將這些增強器和目標類注入代理工廠,再用代理工廠創建物件);
- 代理物件執行目標方法,得到目標方法的攔截器鏈,利用攔截器的鏈式機制,依次進入每一個攔截器進行執行
AOP使用哪種動態代理?
- 當bean的是實作中存在介面或者是Proxy的子類,—jdk動態代理;不存在介面,spring會采用CGLIB來生成代理物件;
- JDK 動態代理主要涉及到 java.lang.reflect 包中的兩個類:Proxy 和 InvocationHandler,
- Proxy 利用 InvocationHandler(定義橫切邏輯) 介面動態創建 目標類的代理物件,
什么是jdk動態代理
- 通過bind方法建立代理與真實物件關系,通過Proxy.newProxyInstance(target)生成代理物件
- 代理物件通過反射invoke方法實作呼叫真實物件的方法
動態代理與靜態代理區別
- 靜態代理,程式運行前代理類的.class檔案就存在了;
- 動態代理:在程式運行時利用反射動態創建代理物件<復用性,易用性,更加集中都呼叫invoke>
CGLIB與JDK動態代理區別
- Jdk必須提供介面才能使用;
- CGLIB不需要,只要一個非抽象類就能實作動態代理
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/229153.html
標籤:java
