Spring框架及七大模塊


此文轉載自:https://blog.csdn.net/m0_46511049/article/details/110283909#commentBox

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不需要,只要一個非抽象類就能實現動態代理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM