<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          開(kāi)工面試必備:Spring 面試 63 連問(wèn)

          共 22118字,需瀏覽 45分鐘

           ·

          2022-02-12 15:29

          點(diǎn)擊關(guān)注公眾號(hào),實(shí)用技術(shù)文章及時(shí)了解

          來(lái)源:blog.csdn.net/wuzhiwei549/article/details/122324261

          Spring原理

          Spring是一個(gè)輕量級(jí)Java開(kāi)發(fā)框架,最早有Rod Johnson創(chuàng)建,目的是為了解決企業(yè)級(jí)應(yīng)用開(kāi)發(fā)的業(yè)務(wù)邏輯層和其他各層的耦合問(wèn)題。它是一個(gè)分層的JavaSE/JavaEE full-stack(一站式)輕量級(jí)開(kāi)源框架,為開(kāi)發(fā)Java應(yīng)用程序提供全面的基礎(chǔ)架構(gòu)支持。Spring負(fù)責(zé)基礎(chǔ)架構(gòu),因此Java開(kāi)發(fā)者可以專注于應(yīng)用程序的開(kāi)發(fā)。

          Spring是一個(gè)全面的、企業(yè)應(yīng)用開(kāi)發(fā)一站式的解決方案,貫穿表現(xiàn)層、業(yè)務(wù)層、持久層。但是它仍然可以和其他的框架無(wú)縫整合。

          Spring 特點(diǎn)

          輕量級(jí): 組件大小與開(kāi)銷兩方面而言Spring都是輕量的。完整的Spring框架可以在一個(gè)大小只有1M多的JAR文件中發(fā)布,并且Spring所需的處理開(kāi)銷也是微不足道的。此外,Spring是非侵入式,典型案例,Spring應(yīng)用中的對(duì)象不依賴于Spring特定的類

          控制反轉(zhuǎn): Spring通過(guò)控制反轉(zhuǎn)(IOC)技術(shù)實(shí)現(xiàn)解耦。一個(gè)對(duì)象依賴的其他對(duì)象會(huì)通過(guò)被動(dòng)的方式傳遞進(jìn)來(lái),而不需要對(duì)象自己創(chuàng)建或者查找依賴。

          面向切面: 支持切面(AOP)編程,并且吧應(yīng)用業(yè)務(wù)邏輯和系統(tǒng)服務(wù)區(qū)分開(kāi)。

          容器: Spring包含并管理應(yīng)用對(duì)象的配置和生命周期,在這個(gè)意義上它是一種容器。可以配置每個(gè)bean如何被創(chuàng)建、銷毀,bean的作用范圍是單例還是每次都生成一個(gè)新的實(shí)例,以及他們是如何相互關(guān)聯(lián)。

          框架集合: 將簡(jiǎn)單的組件配置,組合成為復(fù)雜的框架;應(yīng)用對(duì)象被申明式組合;提供許多基礎(chǔ)功能(事務(wù)管理、持久化框架繼承),提供應(yīng)用邏輯開(kāi)發(fā)接口

          Spring 框架優(yōu)缺點(diǎn)

          優(yōu)點(diǎn)

          • 方便解耦,簡(jiǎn)化開(kāi)發(fā):Spring就是一個(gè)大工廠,可以將所有對(duì)象的創(chuàng)建和依賴關(guān)系的維護(hù),交給Spring管理。
          • AOP編程的支持:Spring提供面向切面編程,可以方便的實(shí)現(xiàn)對(duì)程序進(jìn)行權(quán)限攔截、運(yùn)行監(jiān)控等功能。
          • 聲明式事務(wù)的支持:只需要通過(guò)配置就可以完成對(duì)事務(wù)的管理,而無(wú)需手動(dòng)編程。
          • 方便程序的測(cè)試:Spring對(duì)Junit4支持,可以通過(guò)注解方便的測(cè)試Spring程序。
          • 方便集成各種優(yōu)秀框架:Spring不排斥各種優(yōu)秀的開(kāi)源框架,其內(nèi)部提供了對(duì)各種優(yōu)秀框架的直接支持(如:Struts、Hibernate、MyBatis等)。
          • 降低JavaEE API的使用難度:Spring對(duì)JavaEE開(kāi)發(fā)中非常難用的一些API(JDBC、JavaMail、遠(yuǎn)程調(diào)用等),都提供了封裝,使這些API應(yīng)用難度大大降低。

          缺點(diǎn)

          • Spring依賴反射,反射影響性能
          • 使用門檻升高,入門Spring需要較長(zhǎng)時(shí)間

          Spring 框架中都用到了哪些設(shè)計(jì)模式

          Spring 框架中使用到了大量的設(shè)計(jì)模式,下面列舉了比較有代表性的:

          • 代理模式—在 AOP 和 remoting 中被用的比較多。
          • 單例模式—在 spring 配置文件中定義的 bean 默認(rèn)為單例模式。
          • 模板方法—用來(lái)解決代碼重復(fù)的問(wèn)題。比如. RestTemplate, JmsTemplate, JpaTempl ate。
          • 前端控制器—Spring 提供了 DispatcherServlet 來(lái)對(duì)請(qǐng)求進(jìn)行分發(fā)。
          • 視圖幫助(View Helper )—Spring 提供了一系列的 JSP 標(biāo)簽,高效宏來(lái)輔助將分散的代碼整合在視圖里。
          • 依賴注入—貫穿于 BeanFactory / ApplicationContext 接口的核心理念。
          • 工廠模式—BeanFactory 用來(lái)創(chuàng)建對(duì)象的實(shí)例

          Spring核心組件

          Spring 總共大約有 20 個(gè)模塊, 由 1300 多個(gè)不同的文件構(gòu)成。而這些組件被分別整合在核心容器(Core Container) 、 AOP(Aspect Oriented Programming)和設(shè)備支持(Instrmentation) 、數(shù)據(jù)訪問(wèn)與集成(Data Access/Integeration) 、 Web、 消息(Messaging) 、 Test等 6 個(gè)模塊中。以下是 Spring 5 的模塊結(jié)構(gòu)圖:

          • spring core:提供了框架的基本組成部分,包括控制反轉(zhuǎn)(Inversion of Control,IOC)和依賴注入(Dependency Injection,DI)功能。
          • spring beans:提供了BeanFactory,是工廠模式的一個(gè)經(jīng)典實(shí)現(xiàn),Spring將管理對(duì)象稱為Bean。
          • spring context:構(gòu)建于 core 封裝包基礎(chǔ)上的 context 封裝包,提供了一種框架式的對(duì)象訪問(wèn)方法。
          • spring jdbc:提供了一個(gè)JDBC的抽象層,消除了煩瑣的JDBC編碼和數(shù)據(jù)庫(kù)廠商特有的錯(cuò)誤代碼解析, 用于簡(jiǎn)化JDBC。
          • spring aop:提供了面向切面的編程實(shí)現(xiàn),讓你可以自定義攔截器、切點(diǎn)等。
          • spring Web:提供了針對(duì) Web 開(kāi)發(fā)的集成特性,例如文件上傳,利用 servlet listeners 進(jìn)行 ioc 容器初始化和針對(duì) Web 的 ApplicationContext。
          • spring test:主要為測(cè)試提供支持的,支持使用JUnit或TestNG對(duì)Spring組件進(jìn)行單元測(cè)試和集成測(cè)試。

          Spring 控制反轉(zhuǎn)(IOC)

          控制反轉(zhuǎn)(IOC)概念

          控制反轉(zhuǎn)即IOC (Inversion of Control),它把傳統(tǒng)上由程序代碼直接操控的對(duì)象的調(diào)用權(quán)交給容器,通過(guò)容器來(lái)實(shí)現(xiàn)對(duì)象組件的裝配和管理。

          Spring 通過(guò)一個(gè)配置文件描述 Bean 及 Bean 之間的依賴關(guān)系,利用 Java 語(yǔ)言的反射功能(依賴注入DI)實(shí)例化 Bean 并建立 Bean 之間的依賴關(guān)系。Spring 的 IoC 容器在完成這些底層工作的基礎(chǔ)上,還提供 了 Bean 實(shí)例緩存、生命周期管理、 Bean 實(shí)例代理、事件發(fā)布、資源裝載等高級(jí)服務(wù)。

          Spring 容器高層視圖

          Spring 啟動(dòng)時(shí)讀取應(yīng)用程序提供的 Bean 配置信息,并在 Spring 容器中生成一份相應(yīng)的 Bean 配

          置注冊(cè)表,然后根據(jù)這張注冊(cè)表實(shí)例化 Bean,裝配好 Bean 之間的依賴關(guān)系,為上層應(yīng)用提供準(zhǔn)

          備就緒的運(yùn)行環(huán)境。其中 Bean 緩存池為 HashMap 實(shí)現(xiàn)

          IOC 容器實(shí)現(xiàn)

          BeanFactory-框架基礎(chǔ)設(shè)施

          BeanFactory 是 Spring 框架的基礎(chǔ)設(shè)施,面向 Spring 本身;

          ApplicationContext 面向使用Spring 框架的開(kāi)發(fā)者,幾乎所有的應(yīng)用場(chǎng)合我們都直接使用 ApplicationContext 而非底層的 BeanFactory。

          • BeanDefinitionRegistry 注冊(cè)表:Spring 配置文件中每一個(gè)節(jié)點(diǎn)元素在 Spring 容器里都通過(guò)一個(gè) BeanDefinition 對(duì)象表示,它描述了 Bean 的配置信息。而 BeanDefinitionRegistry 接口提供了向容器手工注冊(cè)BeanDefinition 對(duì)象的方法。
          • BeanFactory 頂層接口:位于類結(jié)構(gòu)樹(shù)的頂端 ,它最主要的方法就是 getBean(String beanName),該方法從容器中返回特定名稱的 Bean,BeanFactory 的功能通過(guò)其他的接口得到不斷擴(kuò)展:
          • ListableBeanFactory:該接口定義了訪問(wèn)容器中 Bean 基本信息的若干方法,如查看 Bean 的個(gè)數(shù)、獲取某一類型Bean 的配置名、查看容器中是否包括某一 Bean 等方法;
          • HierarchicalBeanFactory 父子級(jí):父子級(jí)聯(lián) IoC 容器的接口,子容器可以通過(guò)接口方法訪問(wèn)父容器;通過(guò)HierarchicalBeanFactory 接口, Spring 的 IoC 容器可以建立父子層級(jí)關(guān)聯(lián)的容器體系,子容器可以訪問(wèn)父容器中的 Bean,但父容器不能訪問(wèn)子容器的 Bean。Spring 使用父子容器實(shí)現(xiàn)了很多功能,比如在 Spring MVC 中,展現(xiàn)層 Bean 位于一個(gè)子容器中,而業(yè)務(wù)層和持久層的 Bean 位于父容器中。這樣,展現(xiàn)層 Bean 就可以引用業(yè)務(wù)層和持久層的 Bean,而業(yè)務(wù)層和持久層的 Bean 則看不到展現(xiàn)層的 Bean。
          • ConfigurableBeanFactory:是一個(gè)重要的接口,增強(qiáng)了 IoC 容器的可定制性,它定義了設(shè)置類裝載器、屬性編輯器、容器初始化后置處理器等方法;
          • AutowireCapableBeanFactory 自動(dòng)裝配:定義了將容器中的 Bean 按某種規(guī)則(如按名字匹配、按類型匹配等)進(jìn)行自動(dòng)裝配的方法;
          • SingletonBeanRegistry 運(yùn)行期間注冊(cè)單例 Bean:定義了允許在運(yùn)行期間向容器注冊(cè)單實(shí)例 Bean 的方法;對(duì)于單實(shí)例( singleton)的 Bean 來(lái)說(shuō),BeanFactory 會(huì)緩存 Bean 實(shí)例,所以第二次使用 getBean() 獲取 Bean 時(shí)將直接從IoC 容器的緩存中獲取 Bean 實(shí)例。Spring 在 DefaultSingletonBeanRegistry 類中提供了一個(gè)用于緩存單實(shí)例 Bean 的緩存器,它是一個(gè)用 HashMap 實(shí)現(xiàn)的緩存器,單實(shí)例的 Bean 以beanName 為鍵保存在這個(gè) HashMap 中。
          • 依賴日志框架:在初始化 BeanFactory 時(shí),必須為其提供一種日志框架,比如使用 Log4J, 即在類路徑下提供 Log4J 配置文件,這樣啟動(dòng) Spring 容器才不會(huì)報(bào)錯(cuò)。

          ApplicationContext 面向開(kāi)發(fā)應(yīng)用

          ApplicationContext 由 BeanFactory 派生而來(lái),提供了更多面向?qū)嶋H應(yīng)用的功能。

          ApplicationContext 繼承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基礎(chǔ)

          上,還通過(guò)多個(gè)其他的接口擴(kuò)展了 BeanFactory 的功能:

          • ClassPathXmlApplicationContext:默認(rèn)從類路徑加載配置文件
          • FileSystemXmlApplicationContext:默認(rèn)從文件系統(tǒng)中裝載配置文件
          • ApplicationEventPublisher:讓容器擁有發(fā)布應(yīng)用上下文事件的功能,包括容器啟動(dòng)事件、關(guān)閉事件等。
          • MessageSource:為應(yīng)用提供 i18n 國(guó)際化消息訪問(wèn)的功能;
          • ResourcePatternResolver :所有 ApplicationContext 實(shí)現(xiàn)類都實(shí)現(xiàn)了類似于
          • PathMatchingResourcePatternResolver:通過(guò)帶前綴的 Ant 風(fēng)格的資源文件路徑裝載 Spring 的配置文件。
          • LifeCycle:該接口是 Spring 2.0 加入的,該接口提供了 start()和 stop()兩個(gè)方法,主要用于控制異步處理過(guò)程。在具體使用時(shí),該接口同時(shí)被 ApplicationContext 實(shí)現(xiàn)及具體Bean 實(shí)現(xiàn), ApplicationContext 會(huì)將 start/stop 的信息傳遞給容器中所有實(shí)現(xiàn)了該接口的 Bean,以達(dá)到管理和控制 JMX、任務(wù)調(diào)度等目的。
          • ConfigurableApplicationContext :擴(kuò)展于 ApplicationContext,它新增加了兩個(gè)主要的方法:refresh()和 close(),讓 ApplicationContext 具有啟動(dòng)、刷新和關(guān)閉應(yīng)用上下文的能力。在應(yīng)用上下文關(guān)閉的情況下調(diào)用 refresh()即可啟動(dòng)應(yīng)用上下文,在已經(jīng)啟動(dòng)的狀態(tài)下,調(diào)用 refresh()則清除緩存并重新裝載配置信息,而調(diào)用 close()則可關(guān)閉應(yīng)用上下文。

          BeanFactory 和 ApplicationContext有什么區(qū)別?

          BeanFactory和ApplicationContext是Spring的兩大核心接口,都可以當(dāng)做Spring的容器。其中ApplicationContext是BeanFactory的子接口。

          依賴關(guān)系

          BeanFactory:是Spring里面最底層的接口,包含了各種Bean的定義,讀取bean配置文檔,管理bean的加載、實(shí)例化,控制bean的生命周期,維護(hù)bean之間的依賴關(guān)系。

          ApplicationContext:接口作為BeanFactory的派生,除了提供BeanFactory所具有的功能外,還提供了更完整的框架功能:

          • 繼承MessageSource,因此支持國(guó)際化。
          • 統(tǒng)一的資源文件訪問(wèn)方式。
          • 提供在監(jiān)聽(tīng)器中注冊(cè)bean的事件。
          • 同時(shí)加載多個(gè)配置文件。
          • 載入多個(gè)(有繼承關(guān)系)上下文 ,使得每一個(gè)上下文都專注于一個(gè)特定的層次,比如應(yīng)用的web層。

          加載方式

          BeanFactroy:采用的是延遲加載形式來(lái)注入Bean的,即只有在使用到某個(gè)Bean時(shí)(調(diào)getBean()),才對(duì)該Bean進(jìn)行加載實(shí)例化。這樣,我們就不能發(fā)現(xiàn)一些存在的Spring的配置問(wèn)題。如果Bean的某一個(gè)屬性沒(méi)有注入,BeanFacotry加載后,直至第一次使用調(diào)用getBean方法才會(huì)拋出異常。

          ApplicationContext:它是在容器啟動(dòng)時(shí),一次性創(chuàng)建了所有的Bean。這樣,在容器啟動(dòng)時(shí),我們就可以發(fā)現(xiàn)Spring中存在的配置錯(cuò)誤,這樣有利于檢查所依賴屬性是否注入。ApplicationContext啟動(dòng)后預(yù)載入所有的單實(shí)例Bean,通過(guò)預(yù)載入單實(shí)例bean ,確保當(dāng)你需要的時(shí)候,你就不用等待,因?yàn)樗鼈円呀?jīng)創(chuàng)建好了。

          相對(duì)于基本的BeanFactory,ApplicationContext 唯一的不足是占用內(nèi)存空間。當(dāng)應(yīng)用程序配置Bean較多時(shí),程序啟動(dòng)較慢。

          創(chuàng)建方式

          BeanFactory通常以編程的方式被創(chuàng)建,ApplicationContext還能以聲明的方式創(chuàng)建,如使用ContextLoader。

          注冊(cè)方式

          BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但兩者之間的區(qū)別是:BeanFactory需要手動(dòng)注冊(cè),而ApplicationContext則是自動(dòng)注冊(cè)。

          ApplicationContext通常的實(shí)現(xiàn)

          • FileSystemXmlApplicationContext :此容器從一個(gè)XML文件中加載beans的定義,XML Bean 配置文件的全路徑名必須提供給它的構(gòu)造函數(shù)。
          • ClassPathXmlApplicationContext:此容器也從一個(gè)XML文件中加載beans的定義,這里,你需要正確設(shè)置classpath因?yàn)檫@個(gè)容器將在classpath里找bean配置。
          • WebXmlApplicationContext:此容器加載一個(gè)XML文件,此文件定義了一個(gè)WEB應(yīng)用的所有bean。

          Spring的依賴注入

          其主要實(shí)現(xiàn)方式有兩種:依賴注入和依賴查找。

          依賴注入: 相對(duì)于IoC而言,依賴注入(DI)更加準(zhǔn)確地描述了IoC的設(shè)計(jì)理念。所謂依賴注入(Dependency Injection),即組件之間的依賴關(guān)系由容器在應(yīng)用系統(tǒng)運(yùn)行期來(lái)決定,也就是由容器動(dòng)態(tài)地將某種依賴關(guān)系的目標(biāo)對(duì)象實(shí)例注入到應(yīng)用系統(tǒng)中的各個(gè)關(guān)聯(lián)的組件之中。組件不做定位查詢,只提供普通的Java方法讓容器去決定依賴關(guān)系。

          依賴注入的基本原則

          應(yīng)用組件不應(yīng)該負(fù)責(zé)查找資源或者其他依賴的協(xié)作對(duì)象。配置對(duì)象的工作應(yīng)該由IoC容器負(fù)責(zé),“查找資源”的邏輯應(yīng)該從應(yīng)用組件的代碼中抽取出來(lái),交給IoC容器負(fù)責(zé)。容器全權(quán)負(fù)責(zé)組件的裝配,它會(huì)把符合依賴關(guān)系的對(duì)象通過(guò)屬性(JavaBean中的setter)或者是構(gòu)造器傳遞給需要的對(duì)象。

          依賴注入優(yōu)勢(shì)

          依賴注入之所以更流行是因?yàn)樗且环N更可取的方式:讓容器全權(quán)負(fù)責(zé)依賴查詢,受管組件只需要暴露JavaBean的setter方法或者帶參數(shù)的構(gòu)造器或者接口,使容器可以在初始化時(shí)組裝對(duì)象的依賴關(guān)系。其與依賴查找方式相比,主要優(yōu)勢(shì)為:

          • 查找定位操作與應(yīng)用代碼完全無(wú)關(guān)
          • 不依賴于容器的API,可以很容易地在任何容器以外使用應(yīng)用對(duì)象
          • 不需要特殊的接口,絕大多數(shù)對(duì)象可以做到完全不必依賴容器

          依賴注入實(shí)現(xiàn)方式

          依賴注入是時(shí)下最流行的IoC實(shí)現(xiàn)方式,依賴注入分為接口注入(Interface Injection),Setter方法注入(Setter Injection)和構(gòu)造器注入(Constructor Injection)三種方式。其中接口注入由于在靈活性和易用性比較差,現(xiàn)在從Spring4開(kāi)始已被廢棄。

          • 構(gòu)造器依賴注入:構(gòu)造器依賴注入通過(guò)容器觸發(fā)一個(gè)類的構(gòu)造器來(lái)實(shí)現(xiàn)的,該類有一系列參數(shù),每個(gè)參數(shù)代表一個(gè)對(duì)其他類的依賴
          • Setter方法注入:Setter方法注入是容器通過(guò)調(diào)用無(wú)參構(gòu)造器或無(wú)參static工廠 方法實(shí)例化bean之后,調(diào)用該bean的setter方法,即實(shí)現(xiàn)了基于setter的依賴注入

          構(gòu)造器依賴注入和 Setter方法注入的區(qū)別

          兩種依賴方式都可以使用,構(gòu)造器注入和Setter方法注入。最好的解決方案是用構(gòu)造器參數(shù)實(shí)現(xiàn)強(qiáng)制依賴,setter方法實(shí)現(xiàn)可選依賴。

          WebApplication 體系架構(gòu)

          WebApplicationContext 是專門為 Web 應(yīng)用準(zhǔn)備的,它允許從相對(duì)于 Web 根目錄的路徑中裝載配置文件完成初始化工作。從 WebApplicationContext 中可以獲得ServletContext 的引用,整個(gè) Web 應(yīng)用上下文對(duì)象將作為屬性放置到 ServletContext 中,以便 Web 應(yīng)用環(huán)境可以訪問(wèn) Spring 應(yīng)用上下文。

          Spring Bean 定義

          一個(gè)Spring Bean 的定義包含容器必知的所有配置元數(shù)據(jù),包括如何創(chuàng)建一個(gè)bean,它的生命周期詳情及它的依賴。

          • Spring元數(shù)據(jù)配置方式
          • XML配置文件
          • 基于注解的配置
          • 基于java的配置

          Spring Bean 作用域

          Spring 3 中為 Bean 定義了 5 中作用域,分別為 singleton(單例)、prototype(原型)、request、session 和 global session,5 種作用域說(shuō)明如下:

          • singleton:?jiǎn)卫J剑ǘ嗑€程下不安全)。Spring IoC 容器中只會(huì)存在一個(gè)共享的 Bean 實(shí)例,無(wú)論有多少個(gè)Bean 引用它,始終指向同一對(duì)象。該模式在多線程下是不安全的。Singleton 作用域是Spring 中的缺省作用域,也可以顯示的將 Bean 定義為 singleton 模式,配置為:
          • prototype:原型模式每次使用時(shí)創(chuàng)建。每次通過(guò) Spring 容器獲取 prototype 定義的 bean 時(shí),容器都將創(chuàng)建一個(gè)新的 Bean 實(shí)例,每個(gè) Bean 實(shí)例都有自己的屬性和狀態(tài),而 singleton 全局只有一個(gè)對(duì)象。根據(jù)經(jīng)驗(yàn),對(duì)有狀態(tài)的bean使用prototype作用域,而對(duì)無(wú)狀態(tài)的bean使用singleton 作用域。
          • Request:一次 request 一個(gè)實(shí)例。在一次 Http 請(qǐng)求中,容器會(huì)返回該 Bean 的同一實(shí)例。而對(duì)不同的 Http 請(qǐng)求則會(huì)產(chǎn)生新的 Bean,而且該 bean 僅在當(dāng)前 Http Request 內(nèi)有效,當(dāng)前 Http 請(qǐng)求結(jié)束,該 bean實(shí)例也將會(huì)被銷毀。
          • session:在一次 Http Session 中,容器會(huì)返回該 Bean 的同一實(shí)例。而對(duì)不同的 Session 請(qǐng)求則會(huì)創(chuàng)建新的實(shí)例,該 bean 實(shí)例僅在當(dāng)前 Session 內(nèi)有效。同 Http 請(qǐng)求相同,每一次session 請(qǐng)求創(chuàng)建新的實(shí)例,而不同的實(shí)例之間不共享屬性,且實(shí)例僅在自己的 session 請(qǐng)求內(nèi)有效,請(qǐng)求結(jié)束,則實(shí)例將被銷毀。
          • global Session:在一個(gè)全局的 Http Session 中,容器會(huì)返回該 Bean 的同一個(gè)實(shí)例,僅在使用 portlet context 時(shí)有效。

          Spring處理線程并發(fā)問(wèn)題

          在一般情況下,只有無(wú)狀態(tài)的Bean才可以在多線程環(huán)境下共享,在Spring中,絕大部分Bean都可以聲明為singleton作用域,因?yàn)镾pring對(duì)一些Bean中非線程安全狀態(tài)采用ThreadLocal進(jìn)行處理,解決線程安全問(wèn)題。

          ThreadLocal和線程同步機(jī)制都是為了解決多線程中相同變量的訪問(wèn)沖突問(wèn)題。同步機(jī)制采用了“時(shí)間換空間”的方式,僅提供一份變量,不同的線程在訪問(wèn)前需要獲取鎖,沒(méi)獲得鎖的線程則需要排隊(duì)。而ThreadLocal采用了“空間換時(shí)間”的方式。

          ThreadLocal會(huì)為每一個(gè)線程提供一個(gè)獨(dú)立的變量副本,從而隔離了多個(gè)線程對(duì)數(shù)據(jù)的訪問(wèn)沖突。因?yàn)槊恳粋€(gè)線程都擁有自己的變量副本,從而也就沒(méi)有必要對(duì)該變量進(jìn)行同步了。ThreadLocal提供了線程安全的共享對(duì)象,在編寫多線程代碼時(shí),可以把不安全的變量封裝進(jìn)ThreadLocal。

          Spring Bean 生命周期

          實(shí)例化

          1. 實(shí)例化一個(gè) Bean,也就是我們常說(shuō)的 new。

          IOC 依賴注入

          1. 按照 Spring 上下文對(duì)實(shí)例化的 Bean 進(jìn)行配置,也就是 IOC 注入。

          setBeanName 實(shí)現(xiàn)

          1. 如果這個(gè) Bean 已經(jīng)實(shí)現(xiàn)了 BeanNameAware 接口,會(huì)調(diào)用它實(shí)現(xiàn)的 setBeanName(String)方法,此處傳遞的就是 Spring 配置文件中 Bean 的 id 值

          BeanFactoryAware 實(shí)現(xiàn)

          1. 如果這個(gè) Bean 已經(jīng)實(shí)現(xiàn)了 BeanFactoryAware 接口,會(huì)調(diào)用它實(shí)現(xiàn)的 setBeanFactory,

          setBeanFactory(BeanFactory)傳遞的是 Spring 工廠自身(可以用這個(gè)方式來(lái)獲取其它 Bean,只需在 Spring 配置文件中配置一個(gè)普通的 Bean 就可以)。

          ApplicationContextAware 實(shí)現(xiàn)

          1. 如果這個(gè) Bean 已經(jīng)實(shí)現(xiàn)了 ApplicationContextAware 接口,會(huì)調(diào)用setApplicationContext(ApplicationContext)方法,傳入 Spring 上下文(同樣這個(gè)方式也可以實(shí)現(xiàn)步驟 4 的內(nèi)容,但比 4 更好,因?yàn)?ApplicationContext 是 BeanFactory 的子接口,有更多的實(shí)現(xiàn)方法)

          postProcessBeforeInitialization 接口實(shí)現(xiàn)-初始化預(yù)處理

          1. 如果這個(gè) Bean 關(guān)聯(lián)了 BeanPostProcessor 接口,將會(huì)調(diào)用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor 經(jīng)常被用作是 Bean 內(nèi)容的更改,并且由于這個(gè)是在 Bean 初始化結(jié)束時(shí)調(diào)用那個(gè)的方法,也可以被應(yīng)用于內(nèi)存或緩存技術(shù)。

          init-method

          1. 如果 Bean 在 Spring 配置文件中配置了 init-method 屬性會(huì)自動(dòng)調(diào)用其配置的初始化方法。

          postProcessAfterInitialization

          1. 如果這個(gè) Bean 關(guān)聯(lián)了 BeanPostProcessor 接口,將會(huì)調(diào)用postProcessAfterInitialization(Object obj, String s)方法。

          注:以上工作完成以后就可以應(yīng)用這個(gè) Bean 了,那這個(gè) Bean 是一個(gè) Singleton 的,所以一般情況下我們調(diào)用同一個(gè) id 的 Bean 會(huì)是在內(nèi)容地址相同的實(shí)例,當(dāng)然在 Spring 配置文件中也可以配置非 Singleton。

          Destroy 過(guò)期自動(dòng)清理階段

          1. 當(dāng) Bean 不再需要時(shí),會(huì)經(jīng)過(guò)清理階段,如果 Bean 實(shí)現(xiàn)了 DisposableBean 這個(gè)接口,會(huì)調(diào)用那個(gè)其實(shí)現(xiàn)的 destroy()方法;

          destroy-method 自配置清理

          1. 最后,如果這個(gè) Bean 的 Spring 配置中配置了 destroy-method 屬性,會(huì)自動(dòng)調(diào)用其配置的銷毀方法。

          bean生命周期方法

          bean 標(biāo)簽有兩個(gè)重要的屬性(init-methoddestroy-method)。用它們你可以自己定制

          初始化和注銷方法。它們也有相應(yīng)的注解(@PostConstruct@PreDestroy)。

          ""?class=""?init-method="初始化方法"?destroy-method="銷毀方法">

          什么是Spring的內(nèi)部bean?什么是Spring inner beans?

          在Spring框架中,當(dāng)一個(gè)bean僅被用作另一個(gè)bean的屬性時(shí),它能被聲明為一個(gè)內(nèi)部bean。

          內(nèi)部bean可以用setter注入“屬性”和構(gòu)造方法注入“構(gòu)造參數(shù)”的方式來(lái)實(shí)現(xiàn),內(nèi)部bean通常是匿名的,它們的Scope一般是prototype。

          Spring 依賴注入四種方式構(gòu)造器注入

          /*帶參數(shù),方便利用構(gòu)造器進(jìn)行注入*/
          ?
          ?public?CatDaoImpl(String?message){
          ?
          ?this.?message?=?message;
          ?
          ?}
          <bean?id="CatDaoImpl"?class="com.CatDaoImpl">
          ?
          <constructor-arg?value="?message?">constructor-arg>
          ?
          bean>

          setter 方法注入

          ?public?class?Id?{
          ?
          ?private?int?id;
          ?
          ?public?int?getId()?{?return?id;?}
          ?
          ?public?void?setId(int?id)?{?this.id?=?id;?}
          ?
          }
          <bean?id="id"?class="com.id?">?<property?name="id"?value="123">property>?bean>

          靜態(tài)工廠注入

          靜態(tài)工廠顧名思義,就是通過(guò)調(diào)用靜態(tài)工廠的方法來(lái)獲取自己需要的對(duì)象,為了讓 spring 管理所有對(duì)象,我們不能直接通過(guò)"工程類.靜態(tài)方法()"來(lái)獲取對(duì)象,而是依然通過(guò) spring 注入的形式獲取:

          public?class?DaoFactory?{?//靜態(tài)工廠
          ?
          ?public?static?final?FactoryDao?getStaticFactoryDaoImpl(){
          ?
          ?return?new?StaticFacotryDaoImpl();
          ?
          ?}
          ?
          }
          ?
          public?class?SpringAction?{
          ?
          ?private?FactoryDao?staticFactoryDao;?//注入對(duì)象
          ?
          ?//注入對(duì)象的?set?方法
          ?
          ?public?void?setStaticFactoryDao(FactoryDao?staticFactoryDao)?{
          ?
          ?this.staticFactoryDao?=?staticFactoryDao;
          ?
          ?}
          ?
          }

          ?
          ?
          ?<bean?name="springAction"?class="?SpringAction"?>
          ?
          ?
          ?
          ?<property?name="staticFactoryDao"?ref="staticFactoryDao">property>
          ?
          ?bean>
          ?
          ?
          ?
          <bean?name="staticFactoryDao"?class="DaoFactory"
          ?
          factory-method="getStaticFactoryDaoImpl">
          bean>

          實(shí)例工廠

          實(shí)例工廠的意思是獲取對(duì)象實(shí)例的方法不是靜態(tài)的,所以你需要首先 new 工廠類,再調(diào)用普通的實(shí)例方法:

          ?public?class?DaoFactory?{?//實(shí)例工廠
          ?
          ?public?FactoryDao?getFactoryDaoImpl(){
          ?
          ?return?new?FactoryDaoImpl();

          ?
          ?}
          ?
          }
          ?
          public?class?SpringAction?{
          ?
          ?private?FactoryDao?factoryDao;?//注入對(duì)象
          ?
          ?public?void?setFactoryDao(FactoryDao?factoryDao)?{
          ?
          ?this.factoryDao?=?factoryDao;
          ?
          ?}
          ?
          }
          ?<bean?name="springAction"?class="SpringAction">
          ?
          ?
          ?
          ?<property?name="factoryDao"?ref="factoryDao">property>
          ?
          ?bean>
          ?
          ?
          ?
          <bean?name="daoFactory"?class="com.DaoFactory">bean>
          ?
          <bean?name="factoryDao"?factory-bean="daoFactory"
          ?
          factory-method="getFactoryDaoImpl">
          bean>

          5 種不同方式的自動(dòng)裝配

          Spring 裝配包括手動(dòng)裝配和自動(dòng)裝配,手動(dòng)裝配是有基于 xml 裝配、構(gòu)造方法、setter 方法等自動(dòng)裝配有五種自動(dòng)裝配的方式,可以用來(lái)指導(dǎo) Spring 容器用自動(dòng)裝配方式來(lái)進(jìn)行依賴注入。

          • no:默認(rèn)的方式是不進(jìn)行自動(dòng)裝配,通過(guò)顯式設(shè)置 ref 屬性來(lái)進(jìn)行裝配。
          • byName:通過(guò)參數(shù)名 自動(dòng)裝配,Spring 容器在配置文件中發(fā)現(xiàn) bean 的 autowire 屬性被設(shè)置成 byName,之后容器試圖匹配、裝配和該 bean 的屬性具有相同名字的 bean。
          • byType:通過(guò)參數(shù)類型自動(dòng)裝配,Spring 容器在配置文件中發(fā)現(xiàn) bean 的 autowire 屬性被設(shè)置成 byType,之后容器試圖匹配、裝配和該 bean 的屬性具有相同類型的 bean。如果有多個(gè) bean 符合條件,則拋出錯(cuò)誤。
          • constructor:這個(gè)方式類似于 byType, 但是要提供給構(gòu)造器參數(shù),如果沒(méi)有確定的帶參數(shù)的構(gòu)造器參數(shù)類型,將會(huì)拋出異常。
          • autodetect:首先嘗試使用 constructor 來(lái)自動(dòng)裝配,如果無(wú)法工作,則使用 byType 方式。

          Spring 中注入一個(gè) Java Collection

          Spring 提供了以下四種集合類的配置元素:

          • : 該標(biāo)簽用來(lái)裝配可重復(fù)的 list 值。
          • : 該標(biāo)簽用來(lái)裝配沒(méi)有重復(fù)的 set 值。
          • : 該標(biāo)簽可用來(lái)注入鍵和值可以為任何類型的鍵值對(duì)。
          • : 該標(biāo)簽支持注入鍵和值都是字符串類型的鍵值對(duì)。
          <beans>?
          ??
          ?<bean?id="javaCollection"?class="com.howtodoinjava.JavaCollection">?
          ??
          ?<property?name="customList">?
          ?<list>?
          ?<value>INDIAvalue>?
          ?<value>Pakistanvalue>?
          ?<value>USAvalue>?
          ?<value>UKvalue>?
          ?list>?
          ?property>?
          ?
          ??
          ?<property?name="customSet">?
          ?<set>?
          ?<value>INDIAvalue>?
          ?<value>Pakistanvalue>?
          ?<value>USAvalue>?
          ?<value>UKvalue>?
          ?set>?
          ?property>?
          ?
          ??
          ?<property?name="customMap">?
          ?<map>?
          ?<entry?key="1"?value="INDIA"/>?
          ?<entry?key="2"?value="Pakistan"/>?
          ?<entry?key="3"?value="USA"/>?
          ?<entry?key="4"?value="UK"/>?
          ?map>?
          ?property>?
          ?
          ??
          ?<property?name="customProperies">?
          ?<props>?
          ?<prop?key="admin">[email protected]prop>?
          ?<prop?key="support">[email protected]prop>?
          ?props>?
          ?property>?
          ?
          ?bean>?
          beans>

          使用@Autowired注解自動(dòng)裝配的過(guò)程

          在使用@Autowired注解之前需要在Spring配置文件進(jìn)行配置,

          在啟動(dòng)spring IoC時(shí),容器自動(dòng)裝載了一個(gè)AutowiredAnnotationBeanPostProcessor后置處理器,當(dāng)容器掃描到@Autowied@Resource@Inject時(shí),就會(huì)在IoC容器自動(dòng)查找需要的bean,并裝配給該對(duì)象的屬性。在使用@Autowired時(shí),首先在容器中查詢對(duì)應(yīng)類型的bean:

          • 如果查詢結(jié)果剛好為一個(gè),就將該bean裝配給@Autowired指定的數(shù)據(jù);
          • 如果查詢的結(jié)果不止一個(gè),那么@Autowired會(huì)根據(jù)名稱來(lái)查找;
          • 如果上述查找的結(jié)果為空,那么會(huì)拋出異常。解決方法時(shí),使用required=false

          Spring AOP

          AOP原理

          OOP(Object-Oriented Programming)面向?qū)ο缶幊蹋试S開(kāi)發(fā)者定義縱向的關(guān)系,但并適用于定義橫向的關(guān)系,導(dǎo)致了大量代碼的重復(fù),而不利于各個(gè)模塊的重用。

          AOP(Aspect-Oriented Programming),一般稱為面向切面編程,作為面向?qū)ο蟮囊环N補(bǔ)充,用于將那些與業(yè)務(wù)無(wú)關(guān),但卻對(duì)多個(gè)對(duì)象產(chǎn)生影響的公共行為和邏輯,抽取并封裝為一個(gè)可重用的模塊,這個(gè)模塊被命名為“切面”(Aspect),減少系統(tǒng)中的重復(fù)代碼,降低了模塊間的耦合度,同時(shí)提高了系統(tǒng)的可維護(hù)性。

          AOP 主要應(yīng)用場(chǎng)景有

          • Authentication 權(quán)限
          • Caching 緩存
          • Context passing 內(nèi)容傳遞
          • Error handling 錯(cuò)誤處理
          • Lazy loading 懶加載
          • Debugging 調(diào)試
          • logging, tracing, profiling and monitoring 記錄跟蹤 優(yōu)化 校準(zhǔn)
          • Performance optimization 性能優(yōu)化
          • Persistence 持久化
          • Resource pooling 資源池
          • Synchronization 同步
          • Transactions 事務(wù)

          AOP 核心概念

          • 切面(aspect):類是對(duì)物體特征的抽象,切面就是對(duì)橫切關(guān)注點(diǎn)的抽象
          • 橫切關(guān)注點(diǎn):對(duì)哪些方法進(jìn)行攔截,攔截后怎么處理,這些關(guān)注點(diǎn)稱之為橫切關(guān)注點(diǎn)
          • 連接點(diǎn)(joinpoint):被攔截到的點(diǎn),因?yàn)?Spring 只支持方法類型的連接點(diǎn),所以在 Spring中連接點(diǎn)指的就是被攔截到的方法,實(shí)際上連接點(diǎn)還可以是字段或者構(gòu)造器
          • 切入點(diǎn)(pointcut):對(duì)連接點(diǎn)進(jìn)行攔截的定義
          • 通知(advice):所謂通知指的就是指攔截到連接點(diǎn)之后要執(zhí)行的代碼,通知分為前置、后置、異常、最終、環(huán)繞通知五類
          • 目標(biāo)對(duì)象:代理的目標(biāo)對(duì)象
          • 織入(weave):將切面應(yīng)用到目標(biāo)對(duì)象并導(dǎo)致代理對(duì)象創(chuàng)建的過(guò)程
            • 編譯期:切面在目標(biāo)類編譯時(shí)被織入。AspectJ的織入編譯器是以這種方式織入切面的;
            • 類加載期:切面在目標(biāo)類加載到JVM時(shí)被織入。需要特殊的類加載器,它可以在目標(biāo)類被引入應(yīng)用之前增強(qiáng)該目標(biāo)類的字節(jié)碼。AspectJ5的加載時(shí)織入就支持以這種方式織入切面;
            • 運(yùn)行期:切面在應(yīng)用運(yùn)行的某個(gè)時(shí)刻被織入。一般情況下,在織入切面時(shí),AOP容器會(huì)為目標(biāo)對(duì)象動(dòng)態(tài)地創(chuàng)建一個(gè)代理對(duì)象。SpringAOP就是以這種方式織入切面。
          • 引入(introduction):在不修改代碼的前提下,引入可以在運(yùn)行期為類動(dòng)態(tài)地添加一些方法或字段

          Spring 中的代理

          將 Advice 應(yīng)用于目標(biāo)對(duì)象后創(chuàng)建的對(duì)象稱為代理。在客戶端對(duì)象的情況下,目標(biāo)對(duì)象和代理對(duì)象是相同的。

          Advice + Target Object = Proxy

          AOP 實(shí)現(xiàn)方式

          AOP實(shí)現(xiàn)的關(guān)鍵在于代理模式,AOP代理主要分為靜態(tài)代理和動(dòng)態(tài)代理。

          • AspectJ 靜態(tài)代理的增強(qiáng),所謂靜態(tài)代理,就是AOP框架會(huì)在編譯階段生成AOP代理類,因此也稱為編譯時(shí)增強(qiáng),他會(huì)在編譯階段將AspectJ(切面)織入到Java字節(jié)碼中,運(yùn)行的時(shí)候就是增強(qiáng)之后的AOP對(duì)象。
          • Spring AOP使用的動(dòng)態(tài)代理,所謂的動(dòng)態(tài)代理就是說(shuō)AOP框架不會(huì)去修改字節(jié)碼,而是每次運(yùn)行時(shí)在內(nèi)存中臨時(shí)為方法生成一個(gè)AOP對(duì)象,這個(gè)AOP對(duì)象包含了目標(biāo)對(duì)象的全部方法,并且在特定的切點(diǎn)做了增強(qiáng)處理,并回調(diào)原對(duì)象的方法。

          AOP 兩種代理方式

          Spring 提供了兩種方式來(lái)生成代理對(duì)象: JDK Proxy 和 Cglib,具體使用哪種方式生成由AopProxyFactory 根據(jù) AdvisedSupport 對(duì)象的配置來(lái)決定。默認(rèn)的策略是如果目標(biāo)類是接口,則使用 JDK 動(dòng)態(tài)代理技術(shù),否則使用 Cglib 來(lái)生成代理。

          JDK 動(dòng)態(tài)接口代理

          JDK 動(dòng)態(tài)代理主要涉及到 java.lang.reflect 包中的兩個(gè)類:Proxy 和 InvocationHandler。

          InvocationHandler是一個(gè)接口,通過(guò)實(shí)現(xiàn)該接口定義橫切邏輯,并通過(guò)反射機(jī)制調(diào)用目標(biāo)類的代碼,動(dòng)態(tài)將橫切邏輯和業(yè)務(wù)邏輯編制在一起。

          Proxy 利用 InvocationHandler 動(dòng)態(tài)創(chuàng)建一個(gè)符合某一接口的實(shí)例,生成目標(biāo)類的代理對(duì)象。

          CGLib 動(dòng)態(tài)代理

          CGLib 全稱為 Code Generation Library,是一個(gè)強(qiáng)大的高性能,高質(zhì)量的代碼生成類庫(kù),可以在運(yùn)行期擴(kuò)展 Java 類與實(shí)現(xiàn) Java 接口,CGLib 封裝了 asm,可以再運(yùn)行期動(dòng)態(tài)生成新的 class。和 JDK 動(dòng)態(tài)代理相比較:JDK 創(chuàng)建代理有一個(gè)限制,就是只能為接口創(chuàng)建代理實(shí)例,而對(duì)于沒(méi)有通過(guò)接口定義業(yè)務(wù)方法的類,則可以通過(guò) CGLib 創(chuàng)建動(dòng)態(tài)代理。

          實(shí)現(xiàn)原理

          @Aspect
          ?
          public?class?TransactionDemo?{
          ?
          ?@Pointcut(value="execution(*?com.yangxin.core.service.*.*.*(..))")
          ?
          ?public?void?point(){
          ?
          ?}
          ?
          ?@Before(value="point()")
          ?
          ?public?void?before(){
          ?
          ?System.out.println("transaction?begin");
          ?
          ?}
          ?
          ?@AfterReturning(value?=?"point()")
          ?
          ?public?void?after(){
          ?
          ?System.out.println("transaction?commit");
          ?
          ?}
          ?
          ?@Around("point()")
          ?
          ?public?void?around(ProceedingJoinPoint?joinPoint)?throws?Throwable{
          ?
          ?System.out.println("transaction?begin");
          ?
          ?joinPoint.proceed();
          ?
          ?System.out.println("transaction?commit");
          ?
          ?}?}

          Spring在運(yùn)行時(shí)通知對(duì)象

          通過(guò)在代理類中包裹切面,Spring在運(yùn)行期把切面織入到Spring管理的bean中。代理封裝了目標(biāo)類,并攔截被通知方法的調(diào)用,再把調(diào)用轉(zhuǎn)發(fā)給真正的目標(biāo)bean。當(dāng)代理攔截到方法調(diào)用時(shí),在調(diào)用目標(biāo)bean方法之前,會(huì)執(zhí)行切面邏輯。

          直到應(yīng)用需要被代理的bean時(shí),Spring才創(chuàng)建代理對(duì)象。如果使用的是ApplicationContext的話,在ApplicationContext從BeanFactory中加載所有bean的時(shí)候,Spring才會(huì)創(chuàng)建被代理的對(duì)象。因?yàn)镾pring運(yùn)行時(shí)才創(chuàng)建代理對(duì)象,所以我們不需要特殊的編譯器來(lái)織入SpringAOP的切面。

          Spring只支持方法級(jí)別的連接點(diǎn)

          因?yàn)镾pring基于動(dòng)態(tài)代理,所以Spring只支持方法連接點(diǎn)。Spring缺少對(duì)字段連接點(diǎn)的支持,而且它不支持構(gòu)造器連接點(diǎn)。方法之外的連接點(diǎn)攔截功能,我們可以利用Aspect來(lái)補(bǔ)充。

          在Spring AOP 中,關(guān)注點(diǎn)和橫切關(guān)注的區(qū)別是什么?在 spring aop 中 concern 和 cross-cutting concern 的不同之處

          關(guān)注點(diǎn)(concern)是應(yīng)用中一個(gè)模塊的行為,一個(gè)關(guān)注點(diǎn)可能會(huì)被定義成一個(gè)我們想實(shí)現(xiàn)的一個(gè)功能。

          橫切關(guān)注點(diǎn)(cross-cutting concern)是一個(gè)關(guān)注點(diǎn),此關(guān)注點(diǎn)是整個(gè)應(yīng)用都會(huì)使用的功能,并影響整個(gè)應(yīng)用,比如日志,安全和數(shù)據(jù)傳輸,幾乎應(yīng)用的每個(gè)模塊都需要的功能。因此這些都屬于橫切關(guān)注點(diǎn)。

          Spring通知類型

          在AOP術(shù)語(yǔ)中,切面的工作被稱為通知,實(shí)際上是程序執(zhí)行時(shí)要通過(guò)SpringAOP框架觸發(fā)的代碼段。Spring切面可以應(yīng)用5種類型的通知:

          • 前置通知(Before):在目標(biāo)方法被調(diào)用之前調(diào)用通知功能;
          • 后置通知(After):在目標(biāo)方法完成之后調(diào)用通知,此時(shí)不會(huì)關(guān)心方法的輸出是什么;
          • 返回通知(After-returning ):在目標(biāo)方法成功執(zhí)行之后調(diào)用通知;
          • 異常通知(After-throwing):在目標(biāo)方法拋出異常后調(diào)用通知;
          • 環(huán)繞通知(Around):通知包裹了被通知的方法,在被通知的方法調(diào)用之前和調(diào)用之后執(zhí)行自定義的行為。

          同一個(gè)aspect,不同advice的執(zhí)行順序:

          沒(méi)有異常情況下的執(zhí)行順序:

          • around before advice
          • before advice
          • target method 執(zhí)行
          • around after advice
          • after advice
          • afterReturning

          有異常情況下的執(zhí)行順序:

          • around before advice
          • before advice
          • target method 執(zhí)行
          • around after advice
          • after advice
          • afterThrowing:異常發(fā)生
          • java.lang.RuntimeException: 異常發(fā)生

          Spring MVC

          Spring MVC 原理

          Spring 的模型-視圖-控制器(MVC)框架是圍繞一個(gè) DispatcherServlet 來(lái)設(shè)計(jì)的,這個(gè) Servlet會(huì)把請(qǐng)求分發(fā)給各個(gè)處理器,并支持可配置的處理器映射、視圖渲染、本地化、時(shí)區(qū)與主題渲染等,甚至還能支持文件上傳。

          Http 請(qǐng)求到 DispatcherServlet

          (1) 客戶端請(qǐng)求提交到 DispatcherServlet。

          HandlerMapping 尋找處理器

          (2) 由 DispatcherServlet 控制器查詢一個(gè)或多個(gè) HandlerMapping,找到處理請(qǐng)求的Controller。

          調(diào)用處理器 Controller

          (3) DispatcherServlet 將請(qǐng)求提交到 Controller。

          Controller 調(diào)用業(yè)務(wù)邏輯處理后,返回 ModelAndView

          (4)(5)調(diào)用業(yè)務(wù)處理和返回結(jié)果:Controller 調(diào)用業(yè)務(wù)邏輯處理后,返回 ModelAndView。

          DispatcherServlet 查詢 ModelAndView

          (6)(7)處理視圖映射并返回模型:DispatcherServlet 查詢一個(gè)或多個(gè) ViewResoler 視圖解析器,找到 ModelAndView 指定的視圖。

          ModelAndView 反饋瀏覽器 HTTP

          (8) Http 響應(yīng):視圖負(fù)責(zé)將結(jié)果顯示到客戶端。

          Spring DATA

          Spring ORM理解

          Spring 通過(guò)提供ORM模塊,支持我們?cè)谥苯覬DBC之上使用一個(gè)對(duì)象/關(guān)系映射映射(ORM)工具,Spring 支持集成主流的ORM框架,如Hiberate,JDO和 iBATIS,JPA,TopLink,JDO,OJB 。Spring的事務(wù)管理同樣支持以上所有ORM框架及JDBC。

          解釋JDBC抽象和DAO模塊

          通過(guò)使用JDBC抽象和DAO模塊,保證數(shù)據(jù)庫(kù)代碼的簡(jiǎn)潔,并能避免數(shù)據(jù)庫(kù)資源錯(cuò)誤關(guān)閉導(dǎo)致的問(wèn)題,它在各種不同的數(shù)據(jù)庫(kù)的錯(cuò)誤信息之上,提供了一個(gè)統(tǒng)一的異常訪問(wèn)層。它還利用Spring的AOP 模塊給Spring應(yīng)用中的對(duì)象提供事務(wù)管理服務(wù)。

          Spring DAO 的支持

          Spring DAO(數(shù)據(jù)訪問(wèn)對(duì)象) 使得 JDBC,Hibernate 或 JDO 這樣的數(shù)據(jù)訪問(wèn)技術(shù)更容易以一種統(tǒng)一的方式工作。這使得用戶容易在持久性技術(shù)之間切換。它還允許您在編寫代碼時(shí),無(wú)需考慮捕獲每種技術(shù)不同的異常。

          Spring JDBC API

          • JdbcTemplate
          • SimpleJdbcTemplate
          • NamedParameterJdbcTemplate
          • SimpleJdbcInsert
          • SimpleJdbcCall

          JdbcTemplate是什么

          JdbcTemplate 類提供了很多便利的方法解決諸如把數(shù)據(jù)庫(kù)數(shù)據(jù)轉(zhuǎn)變成基本數(shù)據(jù)類型或?qū)ο螅瑘?zhí)行寫好的或可調(diào)用的數(shù)據(jù)庫(kù)操作語(yǔ)句,提供自定義的數(shù)據(jù)錯(cuò)誤處理。

          使用Spring通過(guò)什么方式訪問(wèn)Hibernate?

          有兩種方式訪問(wèn)Hibernate:

          • 使用 Hibernate 模板和回調(diào)進(jìn)行控制反轉(zhuǎn)
          • 擴(kuò)展 HibernateDAOSupport 并應(yīng)用 AOP 攔截器節(jié)點(diǎn)

          Spring 支持的 ORM

          Spring 支持以下 ORM:

          • Hibernate
          • iBatis
          • JPA (Java Persistence API)
          • TopLink
          • JDO (Java Data Objects)
          • OJB

          如何通過(guò) HibernateDaoSupport 將 Spring 和 Hibernate 結(jié)合起來(lái)?

          用 Spring 的 SessionFactory 調(diào)用 LocalSessionFactory。集成過(guò)程分三步:

          • 配置 the Hibernate SessionFactory
          • 繼承 HibernateDaoSupport
          • 實(shí)現(xiàn)一個(gè) DAO 在 AOP 支持的事務(wù)中裝配

          Spring 支持的事務(wù)管理類型

          Spring 支持兩種類型的事務(wù)管理:

          • 編程式事務(wù)管理:這意味你通過(guò)編程的方式管理事務(wù),給你帶來(lái)極大的靈活性,但是 難維護(hù)。
          • 聲明式事務(wù)管理:這意味著你可以將業(yè)務(wù)代碼和事務(wù)管理分離,你只需用注解和 XML 配置來(lái)管理事務(wù)。

          Spring 框架的事務(wù)管理有哪些優(yōu)點(diǎn)?

          它為不同的事務(wù) API 如 JTA,JDBC,Hibernate,JPA 和 JDO,提供一個(gè)不變 的編程模式。

          它為編程式事務(wù)管理提供了一套簡(jiǎn)單的 API 而不是一些復(fù)雜的事務(wù) API 如 它支持聲明式事務(wù)管理。它和 Spring 各種數(shù)據(jù)訪問(wèn)抽象層很好得集成。

          你更傾向用那種事務(wù)管理類型?

          大多數(shù) Spring 框架的用戶選擇聲明式事務(wù)管理,因?yàn)樗鼘?duì)應(yīng)用代碼的影響最小,因 此更符合一個(gè)無(wú)侵入的輕量級(jí)容器的思想。聲明式事務(wù)管理要優(yōu)于編程式事務(wù)管理, 雖然比編程式事務(wù)管理(這種方式允許你通過(guò)代碼控制事務(wù))少了一點(diǎn)靈活性。

          Spring常用注解

          聲明bean的注解

          • @Component :組件,沒(méi)有明確的角色
          • @Service :在業(yè)務(wù)邏輯層使用
          • @Repository :在數(shù)據(jù)訪問(wèn)層使用
          • @Controller :在展現(xiàn)層使用,控制層的聲明
          • @RestController@Controller@ResponseBody組合,,控制層的聲明

          注入bean的注解

          • @Autowired

          Spring自帶的注解,通過(guò)AutowiredAnnotationBeanPostProcessor 類實(shí)現(xiàn)的依賴注入,作用在CONSTRUCTOR、METHOD、PARAMETER、FIELD、ANNOTATION_TYPE。默認(rèn)是根據(jù)類型(byType )進(jìn)行自動(dòng)裝配的。如果有多個(gè)類型一樣的Bean候選者,需要指定按照名稱(byName )進(jìn)行裝配,則需要配合@Qualifier。

          指定名稱后,如果Spring IOC容器中沒(méi)有對(duì)應(yīng)的組件bean拋出NoSuchBeanDefinitionException。也可以將@Autowired中required配置為false,如果配置為false之后,當(dāng)沒(méi)有找到相應(yīng)bean的時(shí)候,系統(tǒng)不會(huì)拋異常

          • @Inject

          JSR330 (Dependency Injection for Java)中的規(guī)范,需要導(dǎo)入javax.inject.Inject jar包 ,才能實(shí)現(xiàn)注入 作用CONSTRUCTOR、METHOD、FIELD上

          根據(jù)類型進(jìn)行自動(dòng)裝配的,如果需要按名稱進(jìn)行裝配,則需要配合@Named

          • @Resource

          JSR250規(guī)范的實(shí)現(xiàn),在javax.annotation包下,作用TYPE、FIELD、METHOD上。

          默認(rèn)根據(jù)屬性名稱進(jìn)行自動(dòng)裝配的,如果有多個(gè)類型一樣的Bean候選者,則可以通過(guò)name進(jìn)行指定進(jìn)行注入

          java配置類相關(guān)注解

          • @Configuration :聲明當(dāng)前類為配置類,相當(dāng)于xml形式的Spring配置(類上),聲明當(dāng)前類為配置類,其中內(nèi)部組合了@Component注解,表明這個(gè)類是一個(gè)bean(類上)
          • @Bean :注解在方法上,聲明當(dāng)前方法的返回值為一個(gè)bean,替代xml中的方式(方法上)
          • @ComponentScan :用于對(duì)Component進(jìn)行掃描,相當(dāng)于xml中的(類上)
          • @WishlyConfiguration :為@Configuration與@ComponentScan的組合注解,可以替代這兩個(gè)注解

          切面(AOP)相關(guān)注解

          Spring支持AspectJ的注解式切面編程

          • @Aspect:聲明一個(gè)切面(類上),使用@After、@Before、@Around定義建言(advice),可直接將攔截規(guī)則(切點(diǎn))作為參數(shù)。
          • @After :在方法執(zhí)行之后執(zhí)行(方法上)
          • @Before :在方法執(zhí)行之前執(zhí)行(方法上)
          • @Around :在方法執(zhí)行之前與之后執(zhí)行(方法上)
          • @PointCut :聲明切點(diǎn)在java配置類中使用@EnableAspectJAutoProxy注解開(kāi)啟Spring對(duì)AspectJ代理的支持(類上)

          @Bean的屬性支持

          @Scope 設(shè)置Spring容器如何新建Bean實(shí)例(方法上,得有@Bean),其設(shè)置類型包括:

          • Singleton:?jiǎn)卫?一個(gè)Spring容器中只有一個(gè)bean實(shí)例,默認(rèn)模式
          • Protetype:每次調(diào)用新建一個(gè)bean
          • Request:web項(xiàng)目中,給每個(gè)http request新建一個(gè)bean
          • Session :web項(xiàng)目中,給每個(gè)http session新建一個(gè)bean
          • Global:Session給每一個(gè) global http session新建一個(gè)Bean實(shí)例
          • @StepScope:在Spring Batch中還有涉及(Spring Batch 之 背景框架簡(jiǎn)介_(kāi)vincent-CSDN博客)
          • @PostConstruct :由JSR-250提供,在構(gòu)造函數(shù)執(zhí)行完之后執(zhí)行,等價(jià)于xml配置文件中bean的initMethod
          • @PreDestory :由JSR-250提供,在Bean銷毀之前執(zhí)行,等價(jià)于xml配置文件中bean的destroyMethod

          @Value注解

          為屬性注入值,支持如下方式的注入:

          注入普通字符

          注入操作系統(tǒng)屬性

          注入表達(dá)式結(jié)果

          注入其它bean屬性

          注入文件資源

          注入網(wǎng)站資源

          注入配置文件

          @PropertySource 加載配置文件(類上),還需配置一個(gè)PropertySourcesPlaceholderConfigurer的bean。

          環(huán)境切換

          • @Profile :通過(guò)設(shè)定Environment的ActiveProfiles來(lái)設(shè)定當(dāng)前context需要使用的配置環(huán)境。(類或方法上)
          • @Conditional:Spring4中可以使用此注解定義條件話的bean,通過(guò)實(shí)現(xiàn)Condition接口,并重寫matches方法,從而決定該bean是否被實(shí)例化。(方法上)

          異步相關(guān)

          • @EnableAsync:配置類中,通過(guò)此注解開(kāi)啟對(duì)異步任務(wù)的支持,敘事性AsyncConfigurer接口(類上)
          • @Async:在實(shí)際執(zhí)行的bean方法使用該注解來(lái)申明其是一個(gè)異步任務(wù)(方法上或類上所有的方法都將異步,需要@EnableAsync開(kāi)啟異步任務(wù))

          定時(shí)任務(wù)相關(guān)

          • @EnableScheduling :在配置類上使用,開(kāi)啟計(jì)劃任務(wù)的支持(類上)
          • @Scheduled :來(lái)申明這是一個(gè)任務(wù),包括cron,fixDelay,fixRate等類型(方法上,需先開(kāi)啟計(jì)劃任務(wù)的支持)

          @Enable 注解說(shuō)明

          這些注解主要用來(lái)開(kāi)啟對(duì)xxx的支持。

          • @EnableAspectJAutoProxy :開(kāi)啟對(duì)AspectJ自動(dòng)代理的支持
          • @EnableAsync :開(kāi)啟異步方法的支持
          • @EnableScheduling :開(kāi)啟計(jì)劃任務(wù)的支持
          • @EnableWebMvc :開(kāi)啟Web MVC的配置支持
          • @EnableConfigurationProperties :開(kāi)啟對(duì)@ConfigurationProperties注解配置Bean的支持
          • @EnableJpaRepositories :開(kāi)啟對(duì)SpringData JPA Repository的支持
          • @EnableTransactionManagement :開(kāi)啟注解式事務(wù)的支持
          • @EnableCaching :開(kāi)啟注解式的緩存支持

          測(cè)試相關(guān)注解

          • @RunWith :運(yùn)行器,Spring中通常用于對(duì)JUnit的支持
          • @ContextConfiguration:用來(lái)加載配置ApplicationContext,其中classes屬性用來(lái)加載配置類

          SpringMVC部分

          • @EnableWebMvc :在配置類中開(kāi)啟Web MVC的配置支持,如一些ViewResolver或者M(jìn)essageConverter等,若無(wú)此句,重寫WebMvcConfigurerAdapter方法(用于對(duì)SpringMVC的配置)。
          • @Controller :聲明該類為SpringMVC中的Controller
          • @RequestMapping :用于映射Web請(qǐng)求,包括訪問(wèn)路徑和參數(shù)(類或方法上)
          • @ResponseBody :支持將返回值放在response內(nèi),而不是一個(gè)頁(yè)面,通常用戶返回json數(shù)據(jù)(返回值旁或方法上)
          • @RequestBody :允許request的參數(shù)在request體中,而不是在直接連接在地址后面。(放在參數(shù)前)
          • @PathVariable :用于接收路徑參數(shù),比如@RequestMapping(“/hello/{name}”)申明的路徑,將注解放在參數(shù)中前,即可獲取該值,通常作為Restful的接口實(shí)現(xiàn)方法。
          • @RestController :該注解為一個(gè)組合注解,相當(dāng)于@Controller和@ResponseBody的組合,注解在類上,意味著,該Controller的所有方法都默認(rèn)加上了@ResponseBody。
          • @ControllerAdvice :通過(guò)該注解,我們可以將對(duì)于控制器的全局配置放置在同一個(gè)位置,注解了@Controller的類的方法可使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上,這對(duì)所有注解了 @RequestMapping的控制器內(nèi)的方法有效。
          • @ExceptionHandler :用于全局處理控制器里的異常
          • @InitBinder :用來(lái)設(shè)置WebDataBinder,WebDataBinder用來(lái)自動(dòng)綁定前臺(tái)請(qǐng)求參數(shù)到Model中。
          • @ModelAttribute :本來(lái)的作用是綁定鍵值對(duì)到Model里,在@ControllerAdvice中是讓全局的@RequestMapping:都能獲得在此處設(shè)置的鍵值對(duì)。



          我是小富~,如果對(duì)你有用在看關(guān)注支持下,咱們下期見(jiàn)~


          ?往期推薦?

          ??

          面試官問(wèn):訂單30分鐘未支付,自動(dòng)取消,該怎么實(shí)現(xiàn)?

          11 張圖總結(jié)下,微服務(wù)增量拉取
          25 張圖吃透「偏向鎖」,這個(gè) JVM又愛(ài)又恨的崽

          10個(gè)解放雙手的 IDEA 插件,這些代碼真不用手寫(第二彈)

          實(shí)戰(zhàn)干貨!Spring Cloud Gateway 整合 OAuth2.0 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!


          在看點(diǎn)贊轉(zhuǎn)發(fā),是對(duì)我最大的鼓勵(lì)

          整理了幾百本各類技術(shù)電子書(shū),有需要的同學(xué)公眾號(hào)內(nèi)回復(fù)[?666?]自取。技術(shù)群快滿了,想進(jìn)的同學(xué)可以加我好友,和大佬們一起吹吹技術(shù)。

          ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?你的每個(gè)贊和在看,我都喜歡!
          瀏覽 58
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  女人高潮免费视频 | 曰韩黄色毛片免费在线观看 | 国产成人精品片 | www.AV网站 | 亚洲人成小说 |