Spring系列(2):Spring框架

1、Spring定義

Spring是一個開放源代碼的設計層面框架,它解決的是業務邏輯層和其餘各層的鬆耦合問題,所以它將面向接口的編程思想貫穿整個系統應用。css

Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson建立。簡單來講,Spring是一個分層的JavaSE/EE full-stack(一棧式) 輕量級開源框架。html

Spring是一個輕量級控制反轉(IoC)和麪向切面(AOP)的容器框架。java

目的:解決企業應用開發的複雜性
功能:使用基本的JavaBean代替EJB,並提供了更多的企業應用功能
範圍:任何Java應用

優勢:
    1.低侵入式設計,代碼污染極低,【Spring設計爲非侵入式的,意味着你的邏輯代碼不依賴與框架自己。】
    2.獨立於各類應用服務器,基於Spring框架的應用,能夠真正實現Write Once,Run Anywhere的承諾
    3.Spring的DI機制下降了業務對象替換的複雜性,提升了組件之間的解耦【方便解耦,簡化開發】
    4.Spring的AOP支持容許將一些通用任務如安全、事務、日誌等進行集中式管理,從而提供了更好的複用【AOP編程的支持,聲明式事務的支持】
    5.Spring的ORM和DAO提供了與第三方持久層框架的良好整合,並簡化了底層的數據庫訪問
    6.Spring並不強制應用徹底依賴於Spring,開發者可自由選用Spring框架的部分或所有
    7.方便程序的測試,Spring對Junit4支持,能夠經過註解方便的測試Spring程序。
    8.方便集成各類優秀框架。
  • 不使用事務APIs寫代碼就讓一個方法有事務處理功能
  • 不使用remote APIs就可讓本地方法訪問遠程程序
  • 不使用JMX APIs就可讓一個本地方法管理操做
  • 不使用JMS APIs就可讓本地代碼處理消息
特色:
  • Core technologies: dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP.
  • Testing: mock objects, TestContext framework, Spring MVC Test, WebTestClient.
  • Data Access: transactions, DAO support, JDBC, ORM, Marshalling XML.
  • Spring MVC and Spring WebFlux web frameworks.
  • Integration: remoting, JMS, JCA, JMX, email, tasks, scheduling, cache.
  • Languages: Kotlin, Groovy, dynamic languages.

 

 排疑react

  JMX(Java Management Extensions,即Java管理擴展)是一個爲應用程序、設備、系統等植入管理功能的框架。JMX能夠跨越一系列異構操做系統平臺、系統體系結構和網絡傳輸協議,靈活的開發無縫集成的系統、網絡和服務管理應用。git

  JMS(Java Message Service,即Java消息服務)應用程序接口,是一個Java平臺中關於面向消息中間件(MOM)的API,用於在兩個應用程序之間,或分佈式系統中發送消息,進行異步通訊。Java消息服務是一個與具體平臺無關的API。github

  JCA (J2EE 鏈接器架構,Java Connector Architecture)是對J2EE標準集的重要補充。由於它注重的是將Java程序鏈接到非Java程序和軟件包中間件的開發。鏈接器特指基於Java鏈接器架構的源適配器web

2、Spring框架特色

   Spring是一個開源框架,它由Rod Johnson建立。它是爲了解決企業應用開發的複雜性而建立的。Spring使用基本的JavaBean來完成之前只可能由EJB完成的事情。然而,Spring的用途不只限於服務器端的開發。從簡單性、可測試性和鬆耦合的角度而言,任何Java應用均可以從Spring中受益。
   Spring是一個輕量級的控制反轉(IoC)和麪向切面(AOP)的容器框架。
   輕量——從 大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架能夠在一個大小隻有1MB多的JAR文件裏發佈。而且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應用中的對象不依賴於Spring的特定類。
   控制反轉——Spring經過一種稱做控制反轉(IoC)的技術促進了鬆耦合。當應用了IoC,一個對象依賴的其它對象會經過被動的方式傳遞進來,而不是這個對象本身建立或者查找依賴對象。你能夠認爲IoC與JNDI相反——不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。 【工廠模式】
   面向切面——Spring提供了面向切面編程的豐富支持,容許經過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該作的——完成業務邏輯——僅此而已。它們並不負責(甚至是意識)其它的系統級關注點,例如日誌或事務支持。 【動態代理】
   容器——Spring 包含並管理應用對象的配置和生命週期,在這個意義上它是一種容器,你能夠配置你的每一個bean如何被建立——基於一個可配置原型(prototype),你的bean能夠建立一個單獨的實例或者每次須要時都生成一個新的實例——以及它們是如何相互關聯的。然而,Spring不該該被混同於傳統的重量級的EJB容器,它們常常是龐大與笨重的,難以使用。
   框架——Spring能夠將簡單的組件配置、組合成爲複雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件裏。Spring也提供了不少基礎功能(事務管理、持久化框架集成等等),將應用邏輯的開發留給了你。    
   MVC——Spring的做用是整合,但不只僅限於整合,Spring 框架能夠被看作是一個企業解決方案級別的框架。客戶端發送請求,服務器控制器(由DispatcherServlet實現的)完成請求的轉發,控制器調用一個用於映射的類HandlerMapping,該類用於將請求映射到對應的處理器來處理請求。HandlerMapping 將請求映射到對應的處理器Controller(至關於Action)在Spring 當中若是寫一些處理器組件,通常實現Controller 接口,在Controller 中就能夠調用一些Service 或DAO 來進行數據操做 ModelAndView 用於存放從DAO 中取出的數據,還能夠存放響應視圖的一些數據。 若是想將處理結果返回給用戶,那麼在Spring 框架中還提供一個視圖組件ViewResolver,該組件根據Controller 返回的標示,找到對應的視圖,將響應response 返回給用戶。
  全部Spring的這些特徵使你可以編寫更乾淨、更可管理、而且更易於測試的代碼。它們也爲Spring中的各類模塊提供了基礎支持。
 

3、Spring框架

4.x以前spring

 

Spring 框架是一個分層架構,由 7 個定義良好的模塊組成。

Spring 模塊構建在覈心容器之上,核心容器定義了建立、配置和管理 bean 的方式,組成Spring框架的每一個模塊(或組件)均可以單獨存在,或者與其餘一個或多個模塊聯合實現。每一個模塊的功能以下:
    1、Spring Core:核心容器提供 Spring 框架的基本功能(Spring Core)。核心容器的主要組件是 BeanFactory,它是工廠模式的實現。BeanFactory 使用控制反轉(IOC) 模式將應用程序的配置和依賴性規範與實際的應用程序代碼分開。它的BeanFactory消除了應用對Singleton和Factory的依賴。 2、Spring Context:Spring 上下文是一個配置文件,向 Spring框架提供上下文信息。Spring 上下文包括企業服務,例如JNDI、EJB、電子郵件、國際化、校驗和調度功能。 3、Spring AOP:經過配置管理特性,Spring AOP 模塊直接將面向切面的編程功能集成到了 Spring 框架中。因此,能夠很容易地使 Spring 框架管理的任何對象支持AOP。Spring AOP 模塊爲基於 Spring 的應用程序中的對象提供了事務管理服務。經過使用 Spring AOP,不用依賴 EJB 組件,就能夠將聲明性事務管理集成到應用程序中。 4、Spring DAO:JDBC DAO抽象層提供了有意義的異常層次結構,可用該結構來管理異常處理和不一樣數據庫供應商拋出的錯誤消息。異常層次結構簡化了錯誤處理,而且極大地下降了須要編寫的異常代碼數量(例如打開和關閉鏈接)。Spring DAO 的面向 JDBC 的異常聽從通用的 DAO 異常層次結構。 5、Spring ORM:Spring 框架插入了若干個ORM框架,從而提供了 ORM 的對象關係工具,其中包括JDO、Hibernate和iBatisSQL Map。全部這些都聽從 Spring 的通用事務和 DAO 異常層次結構。 6、Spring Web 模塊:Web 上下文模塊創建在應用程序上下文模塊之上,爲基於 Web 的應用程序提供了上下文。因此,Spring框架支持與 Jakarta Struts 的集成。Web 模塊還簡化了處理多部分請求以及將請求參數綁定到域對象的工做。提供了面向Web的綜合特性,如使用Servlet監聽器的Context初始化、文件上傳等功能。此外它也用於同其他Web框架的集成。 七、Spring MVC 框架:MVC框架是一個全功能的構建 Web應用程序的 MVC 實現。經過策略接口,MVC框架變成爲高度可配置的,MVC 容納了大量視圖技術,其中包括 JSP、Velocity、Tiles、iText 和 POI模型由javabean構成,存放於Map;視圖是一個接口,負責顯示模型;控制器表示邏輯代碼,是Controller的實現。Spring框架的功能能夠用在任何J2EE服務器中,大多數功能也適用於不受管理的環境。Spring 的核心要點是:支持不綁定到特定 J2EE服務的可重用業務和數據訪問對象。毫無疑問,這樣的對象能夠在不一樣J2EE 環境(Web 或EJB)、獨立應用程序、測試環境之間重用。

 

下面這張圖來自spring4.x的文檔。目前最新的5.x版本中右面的portlet組件已經被廢棄掉,同時增長了用於異步響應式處理的WebFlux組件。數據庫

  依賴關係以下:express

  

 

1 核心容器
  核心容器由spring-core、spring-beans、spring-context、spring-context和spring-expression 5個模塊構成。
  spring-core和spring-beans模塊爲框架提供最基本的功能,包括IoC和依賴注入。BeanFactory是一個工廠的實現類【工廠模式】。它能夠免除用戶手動建立單例類而且對象之間解耦。
  context(spring-core)模塊基於spring-beans和BeanFactory兩個模塊,容許以框架方式訪問對象,這相似於JNDI。Context模塊繼承了Beans模塊,並支持國際化、事件傳播、資源加載等。Context模塊支持Java EE特性,如EJB、JMX、遠程訪問。spring-context接口是Contet模塊的重點。spring-context-support提供將第三方庫集成到Spring的功能,如緩存(EhCache,JCache)和任務調度(CommonJ,Quartz)等。
  spring-expression模塊提供強有力的在運行時查詢和操做對象的語言。這種語言支持獲取和設置屬性、方法執行、獲取數組或集合中的對象、邏輯計算、命名變量,在Spring的IoC容器中得到對象。
2 AOP 和 Instrumentation
  spring-aop模塊提供切面編程的實現。能夠自定義方法攔截和切入點。
  spring-aspects模塊提供與AspectJ的集成。
  spring-instrument模塊爲特定的服務器提供類加載服務。spring-instrument模塊是集成了Tomcat。
3 消息
  Spring4提供了spring-messaging模塊,主要類有Message,MessageChannel,MessageHandler。這個模塊還包含一些映射消息到方法的註解,相似於Spring MVC基於編程模式的註解。
4 數據訪問/集成
  這一層由JDBC、ORM、OXM、JMS、和事物模塊組成。
  spring-jdbc模塊,主要爲了解決數據庫繁多的問題,應用此可不須要關注使用的數據庫。
  spring-tx模塊提供編程式或聲明式事務處理。
  spring-orm模塊提供流行的對象關係映射的APIs,包含JPA和Hibernate.
  spring-oxm模塊提供對Object/XML映射的支持,例如JAXB,Castor,JiBX和XStream。
  spring-jms模塊(Java消息服務)包含生成和消費消息的功能。在Spring4.1之後,它集成了spring-messaging模塊。
5 Web
  Web層包含spring-web、spring-webmvc和spring-websocket 3個模塊。
  spring-web模塊提供面向Web方法的集成特性,例如多部分文件上傳、經過監聽初始化IoC容器和麪向Web的Context,還包含HTTP客戶端和對遠程的支持。
  spring-webmvc模塊(也被稱做Web-Servlet模塊)包含Spring MVC框架。
  spring-websocket模塊提供對socket的全面支持6 測試
  spring-test模塊經過JUnit或者TestNG來對Spring的模塊進行單元測試和集成測試。它提供一致的Spring 的ApplicationContexts 和context的緩存。它還提供mock對象讓你測試你的代碼。

 

4、Spring機制與實現

  http://www.javashuo.com/article/p-waxabopz-kw.html

4.1 AOP

  AOP:AOP的實現是經過代理模式,在調用對象的某個方法時,執行插入的切面邏輯。實現的方式有動態代理也叫運行時加強,好比jdk代理、CGLIB靜態代理是在編譯時進行織入或類加載時進行織入,好比AspectJ。關於AOP還須要瞭解一下對應的Aspect、pointcut、advice等註解和具體使用方式。 

Advice(通知、切面): 某個鏈接點所採用的處理邏輯,也就是向鏈接點注入的代碼, AOP在特定的切入點上執行的加強處理。
  1.1 @Before: 標識一個前置加強方法,至關於BeforeAdvice的功能.
  1.2 @After: final加強,無論是拋出異常或者正常退出都會執行.
  1.3 @AfterReturning: 後置加強,似於AfterReturningAdvice, 方法正常退出時執行.
  1.4 @AfterThrowing: 異常拋出加強,至關於ThrowsAdvice.
  1.5 @Around: 環繞加強,至關於MethodInterceptor.
JointPoint(鏈接點):程序運行中的某個階段點,好比方法的調用、異常的拋出等。
Pointcut(切入點): JoinPoint的集合,是程序中須要注入Advice的位置的集合,指明Advice要在什麼樣的條件下才能被觸發,在程序中主要體現爲書寫切入點表達式。
Advisor(加強): 是PointCut和Advice的綜合體,完整描述了一個advice將會在pointcut所定義的位置被觸發。
@Aspect(切面): 一般是一個類的註解,裏面能夠定義切入點和通知
AOP Proxy:AOP框架建立的對象,代理就是目標對象的增強。Spring中的AOP代理可使JDK動態代理,也能夠是CGLIB代理,前者基於接口,後者基於子類。

 

4.2 placeHolder動態替換

  placeHolder動態替換主要須要瞭解替換髮生的時間,是在bean definition建立完成後,bean初始化以前,是經過實現BeanFactoryPostProcessor接口實現的。主要實現方式有PropertyPlaceholderConfigurer和PropertySourcesPlaceholderConfigurer。這兩個類實現邏輯不同,spring boot使用PropertySourcesPlaceholderConfigurer實現。

  它們和應用的邏輯無關,只和當前環境、當前系統用戶相關。(不能硬編碼)      

  • 數據庫服務器IP地址、端口、用戶名;
  • 用來保存上傳資料的目錄。
  • 一些參數,諸如是否打開cache、加密所用的密鑰名稱等等。

4.3 事務

事務須要了解spring 中對事務規定的隔離類型和事務傳播類型。要知道事務的隔離級別是由具體的數據庫來實現的。事務的傳播類型,能夠重點了解最經常使用的REQUIRED和SUPPORTS類型。

1. 兩大事務管理方式

  spring支持編程式事務管理聲明式事務管理兩種方式。

        編程式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於編程式事務管理,spring推薦使用TransactionTemplate。

        聲明式事務管理創建在AOP之上的。其本質是對方法先後進行攔截,而後在目標方法開始以前建立或者加入一個事務,在執行完目標方法以後根據執行狀況提交或者回滾事務。聲明式事務最大的優勢就是不須要經過編程的方式管理事務,這樣就不須要在業務邏輯代碼中摻瑣事務管理的代碼,只需在配置文件中作相關的事務規則聲明(或經過基於@Transactional註解的方式),即可以將事務規則應用到業務邏輯中。

       顯然聲明式事務管理要優於編程式事務管理,這正是spring倡導的非侵入式的開發方式。聲明式事務管理使業務代碼不受污染,一個普通的POJO對象,只要加上註解就能夠得到徹底的事務支持。和編程式事務相比,聲明式事務惟一不足地方是,後者的最細粒度只能做用到方法級別,沒法作到像編程式事務那樣能夠做用到代碼塊級別。可是即使有這樣的需求,也存在不少變通的方法,好比,能夠將須要進行事務管理的代碼塊獨立爲方法等等。

        聲明式事務管理也有兩種經常使用的方式,一種是基於tx和aop名字空間的xml配置文件,另外一種就是基於@Transactional註解。顯然基於註解的方式更簡單易用,更清爽。

 

Spring配置聲明式事務:
    * 配置DataSource
    * 配置事務管理器
    * 事務的傳播特性
    * 那些類那些方法使用事務

Spring配置文件中關於事務配置老是由三個組成部分,分別是DataSource、TransactionManager和代理機制這三部分,不管哪一種配置方式,通常變化的只是代理機制這部分。

    DataSource、TransactionManager這兩部分只是會根據數據訪問方式有所變化,好比使用Hibernate進行數據訪問 時,DataSource實際爲SessionFactory,TransactionManager的實現爲 HibernateTransactionManager。

根據代理機制的不一樣,Spring事務的配置又有幾種不一樣的方式:
    第一種方式:每一個Bean都有一個代理
    第二種方式:全部Bean共享一個代理基類
    第三種方式:使用攔截器
    第四種方式:使用tx標籤配置的攔截器
    第五種方式:全註解

 

  


2. 五大隔離級別

  1. ISOLATION_DEFAULT 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別.另外四個與JDBC的隔離級別相對應【默認】
  2. ISOLATION_READ_UNCOMMITTED 這是事務最低的隔離級別,它充許別外一個事務能夠看到這個事務未提交的數據。這種隔離級別會產生髒讀,不可重複讀和幻像讀【隔離級別最低,併發性能高 】
  3. ISOLATION_READ_COMMITTED 保證一個事務修改的數據提交後才能被另一個事務讀取。另一個事務不能讀取該事務未提交的數據。這種事務隔離級別能夠避免髒讀出現,可是可能會出現不可重複讀和幻像讀。【鎖定正在讀取的行】
  4. ISOLATION_REPEATABLE_READ 這種事務隔離級別能夠防止髒讀,不可重複讀。可是可能出現幻像讀。它除了保證一個事務不能讀取另外一個事務未提交的數據外,還保證了避免下面的狀況產生(不可重複讀)。【鎖定所讀取的全部行】
  5. ISOLATION_SERIALIZABLE 這是花費最高代價可是最可靠的事務隔離級別。事務被處理爲順序執行。除了防止髒讀,不可重複讀外,還避免了幻像讀。【鎖表】

3. 七大事務傳播類型

  1. PROPAGATION_REQUIRED 若是存在一個事務,則支持當前事務。若是沒有事務則開啓一個新的事務。【默認】
  2. PROPAGATION_SUPPORTS 若是存在一個事務,支持當前事務。若是沒有事務,則非事務的執行。可是對於事務同步的事務管理器,PROPAGATION_SUPPORTS與不使用事務有少量不一樣。
  3. PROPAGATION_MANDATORY 若是已經存在一個事務,支持當前事務。若是沒有一個活動的事務,則拋出異常。
  4. PROPAGATION_REQUIRES_NEW 老是開啓一個新的事務。若是一個事務已經存在,則將這個存在的事務掛起。
  5. PROPAGATION_NOT_SUPPORTED 老是非事務地執行,並掛起任何存在的事務。
  6. PROPAGATION_NEVER 老是非事務地執行,若是存在一個活動事務,則拋出異常
  7. PROPAGATION_NESTED若是一個活動的事務存在,則運行在一個嵌套的事務中. 若是沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行
若是子事務回滾,父事務會回滾到進入子事務前創建的save point,而後嘗試其餘的事務或者其餘的業務邏輯,父事務以前的操做不會受到影響,更不會自動回滾。
若是父事務回滾,子事務也會跟着回滾。由於父事務結束以前,子事務是不會提交的,由於子事務是父事務的一部分。
事務的提交:子事務先提交,父事務再提交。
子事務是父事務的一部分,由父事務統一提交。

4. 事務超時

      所謂事務超時,就是指一個事務所容許執行的最長時間,若是超過該時間限制但事務尚未完成,則自動回滾事務

  在 TransactionDefinition 中以 int 的值來表示超時時間,其單位是秒。

  默認設置爲底層事務系統的超時值,若是底層數據庫事務系統沒有設置超時值,那麼就是none,沒有超時限制。

 

5. 事務只讀屬性

      只讀事務用於客戶代碼只讀但不修改數據的情形,只讀事務用於特定情景下的優化,好比使用Hibernate的時候。默認爲讀寫事務。

  「只讀事務」僅僅是一個性能優化的推薦配置而已,並不是強制你要這樣作不可

  「只讀事務」並非一個強制選項,它只是一個「暗示」,提示數據庫驅動程序和數據庫系統,這個事務並不包含更改數據的操做,那麼JDBC驅動程序和數據庫就有可能根據這種狀況對該事務進行一些特定的優化,比方說不安排相應的數據庫鎖,以減輕事務對數據庫的壓力,畢竟事務也是要消耗數據庫的資源的。 可是你非要在「只讀事務」裏面修改數據,也並不是不能夠,只不過對於數據一致性的保護不像「讀寫事務」那樣保險而已。 

6. spring事務回滾規則

   Spring、EJB的聲明式事務默認狀況下都是在拋出unchecked exception後纔會觸發事務的回滾

   unchecked異常,即運行時異常runntimeException 回滾事務;

   checked異常,即Exception可try{}捕獲的不會回滾.固然也可配置spring參數讓其回滾. 

指示spring事務管理器回滾一個事務的推薦方法是在當前事務的上下文內拋出異常。

spring事務管理器會捕捉任何未處理的異常,而後依據規則決定是否回滾拋出異常的事務。
默認配置下,spring只有在拋出的異常爲運行時unchecked異常時纔回滾該事務,也就是拋出的異常爲RuntimeException的子類(Errors也會致使事務回滾),而拋出checked異常則不會致使事務回滾
能夠明確的配置在拋出那些異常時回滾事務,包括checked異常。 也能夠明肯定義那些異常拋出時不回滾事務。 還能夠編程性的經過setRollbackOnly()方法來指示一個事務必須回滾,在調用完setRollbackOnly()後你所能執行的惟一操做就是回滾。

讓Exception異常也進行回滾操做,在調用該方法前加上: @Transactional(rollbackFor = Exception.class)
讓RuntimeException不進行回滾操做,在調用該方法前加上: @Transactional(rollbackFor = RuntimeException.class)
在整個方法運行前就不會開啓事務: @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true),這樣就作成一個只讀事務,能夠提升效率

 

4.4 4大核心接口/類

  1. ApplicationContext保存了ioc的整個應用上下文,能夠經過其中的beanfactory獲取到任意到bean;
  2. BeanFactory主要的做用是根據bean definition來建立具體的bean;
  3. BeanWrapper是對Bean的包裝,通常狀況下是在spring ioc內部使用,提供了訪問bean的屬性值、屬性編輯器註冊、類型轉換等功能,方便ioc容器用統一的方式來訪問bean的屬性;
  4. FactoryBean經過getObject方法返回實際的bean對象,例如motan框架中referer對service的動態代理就是經過FactoryBean來實現的。

 

4.5 7種Scope

Scopebean的scope是指bean的做用域,request、session、global-session是在web服務中使用的scope

  1. singleton默認狀況下是單例模式,這也是使用最多的一種方式;
  2. prototype多例模式,即每次從beanFactory中獲取bean都會建立一個新的bean。
  3. request每次請求都建立一個實例,
  4. session是在一個會話週期內保證只有一個實例。
  5. global-session在5.x版本中已經不在使用,
  6. Application保證在一個ServletContext中只建立一個實例。
  7. Websocket保證在一個WebSocket中只建立一個實例。

4.6 5大事件機制

一、基本概念

    1)事件驅動模型

    當事件被觸發的時候,將事件加入一個事件隊列,而後經過主程序不斷輪訓事件隊列,處理目標函數。常見的事件驅動如鼠標點擊事件、IO事件等,觀察者設計模式就是事件驅動的一個很好實現。

    2)消息驅動模型/發佈訂閱模型

    本質上講,事件驅動和消息驅動至關,只是各自應用在不一樣的場景下。事件模式耦合高,同模塊內好用;消息模式耦合低,跨模塊好用。

二、五大標準事件

 

  https://blog.csdn.net/u014746965/article/details/78480159

 在spring中提供的標準事件:

    1)ContextRefreshEvent,當ApplicationContext容器初始化完成或者被刷新的時候,就會發布該事件。

    2)ContextStartedEvent,當ApplicationContext啓動的時候發佈事件,即調用ConfigurableApplicationContext接口的start方法的時候

    3)ContextStoppedEvent,當ApplicationContext容器中止的時候發佈事件,即調用ConfigurableApplicationContext的close方法的時候

    4)ContextClosedEvent,當ApplicationContext關閉的時候發佈事件,即調用ConfigurableApplicationContext的close方法的時候,關閉指的是全部的單例Bean都被銷燬。

    5)equestHandledEvent,只能用於DispatcherServlet的web應用,Spring處理用戶請求結束後,系統會觸發該事件。

 

三、Spring事件機制實現

    事件,ApplicationEvent,繼承自EventObject。

    事件監聽器,ApplicationListener,是一個接口,繼承自EventListener,實際中須要實現其onApplicationEvent方法。

    事件發佈,ApplicationEventPublisher,是一個接口,包含publishEvent()方法,ApplicationContext繼承了該接口,在AbstractApplicationContext中實現裏事件的發佈接口。

 Spring是如何經過事件找到對應的監聽器的呢?Spring利用反射機制經過getBeansOfType獲取全部繼承了ApplicationListener接口的監聽器,而後把監聽器放到註冊表中

 

五.Spring應用

5.1 經常使用註釋

a.類型類註釋:

@Component 是一個泛化的概念,僅僅表示一個組件 (Bean) ,能夠做用在任何層次。

@Service 標註業務層組件,可是目前該功能與 @Component 相同。自動根據bean的類名實例化一個首寫字母爲小寫的bean,例如Chinese實例化爲chinese,若是須要本身更名字則:@Service("你本身改的bean名")。  

@Constroller 標註控制層組件,可是目前該功能與 @Component 相同。

@Repository 標註持久層組件,用於標註數據訪問組件,即DAO組件,標識爲 Spring Bean。

@Configuration 用於定義配置類,可替換xml配置文件,被註解的類內部包含有一個或多個被@Bean註解的方法,至關於把該類做爲spring的xml配置文件中的<beans>,做用爲:配置spring容器(應用上下文)

@Bean 標註在方法上(返回某個實例的方法),等價於spring的xml配置文件中的<bean>,做用爲:註冊bean對象

1. 在目前的 Spring 版本中,@Constroller,@Service ,@Repository這 3 個註釋和 @Component 是等效的,可是從註釋類的命名上,很容易看出這 3 個註釋分別和持久層、業務層和控制層(Web 層)相對應。
2. 爲了讓 Spring 可以掃描類路徑中的類並識別出注解,須要在 XML 配置文件中啓用Bean 的自動掃描功能,這能夠經過<context:component-scan/>實現。
3. @Configuration註解的配置類有以下要求:
    @Configuration不能夠是final類型;
    @Configuration不能夠是匿名類;
    嵌套的configuration必須是靜態類。
4. 其中component和bean註解的區別以下:
    @Component註解在類上使用代表這個類是個組件類,須要Spring爲這個類建立bean。 @Bean註解使用在方法上,告訴Spring這個方法將會返回一個Bean對象,須要把返回的對象註冊到Spring的應用上下文中 @Configuration。

b.設置類註解

@Require 註解做用於Bean的 setter 方法上,用於檢查一個Bean的屬性的值在配置期間是否被賦予或設置(populated),不然,容器會拋出一個BeanInitializationException異常。

@Autowire和@Resource都是Spring支持的註解方式動態裝配bean。做用範圍在字段上,均無需在寫setter方法

@Autowire默認按照類型(by-type)裝配,默認狀況下要求依賴對象必須存在。若是使用按照名稱(by-name)裝配,需結合@Qualifier註解使用,即

@Scope註解是springIoc容器中的一個做用域

1. @Autowire默認按照類型(by-type)裝配,默認狀況下要求依賴對象必須存在。
    若是容許依賴對象爲null,需設置required屬性爲false,即
    @Autowire(required=false)
    private InjectionBean beanName;

    若是使用按照名稱(by-name)裝配,需結合@Qualifier註解使用,即
    @Autowire @Qualifier("beanName")
    private InjectionBean beanName;

    說明
    @Autowire按照名稱(by-name)裝配,則
    @Autowire + @qualifier("") = @Resource(name="")

2. @Resource
  @Resource默認按照名稱(by-name)裝配,名稱能夠經過name屬性指定。若是沒有指定name:1.當註解在字段上時,默認取name=字段名稱裝配。2.當註解在setter方法上時,默認取name=屬性名稱裝配。當按照名稱(by-name)裝配未匹配時,按照類型(by-type)裝配。當顯示指定name屬性後,只能按照名稱(by-name)裝配。
  @Resoure裝配順序
    1. 若是同時指定name和type屬性,則找到惟一匹配的bean裝配,未找到則拋異常;
    2. 若是指定name屬性,則按照名稱(by-name)裝配,未找到則拋異常;
    3. 若是指定type屬性,則按照類型(by-type)裝配,未找到或者找到多個則拋異常;
    4. 既未指定name屬性,又未指定type屬性,則按照名稱(by-name)裝配;若是未找到,則按照類型(by-type)裝配。
  

  https://blog.csdn.net/xxliuboy/article/details/86441832

3. @Scope a.singleton單例模式 -- 全局有且僅有一個實例【默認】 b.prototype原型模式 -- 每次獲取Bean的時候會有一個新的實例 c.request -- request表示該針對每一次HTTP請求都會產生一個新的bean,同時該bean僅在當前HTTP request內有效 d.session -- session做用域表示該針對每一次HTTP請求都會產生一個新的bean,同時該bean僅在當前HTTP session內有效 e.globalsession -- global session做用域相似於標準的HTTP Session做用域,不過它僅僅在基於portlet的web應用中才有意義
  
   @Scope(value = "prototype")

 

c.web類註解

路徑匹配註解

@GetMapping:用於將Http Get 請求映射到特定處理程序方法的註釋。具體來講就是:@GetMapping是一個做爲快捷方式的組合註釋 @RequestMapping(method = RequestMethod.GET)。

@PostMapping:用於將Http Post 請求映射到特定處理程序方法的註釋。具體來講就是:@PostMapping是一個做爲快捷方式的組合註釋@RequestMapping(method = RequestMethod.POST)。

@RequestMapping:通常狀況下都是用@RequestMapping(method = RequestMethod),由於@RequestMapping能夠直接替代以上兩個註解,可是以上兩個註解並不能替代@RequestMapping。

相似組合註解還有:@PutMapping、@DeleteMapping、@PatchMapping

總結下來就是@PostMapping和@GetMapping均可以用@RequestMapping代替,通常能夠統一寫成@RequestMapping,可是不利於其餘人對代碼的閱讀和理解!仍是建議分開寫。

參數獲取註解

@PathVaribale 獲取url中的數據

@RequestParam 獲取請求參數的值

@ResponseBody: responseBody表示服務器返回的時候以一種什麼樣的方式進行返回, 將內容或對象做爲 HTTP 響應正文返回,值有不少,通常設定爲json

@RequestBody:通常是post請求的時候纔會使用這個請求,把參數丟在requestbody裏面

@RequestMapping("/hello/{id}")
    public String getDetails(@PathVariable(value="id") String id,
    @RequestParam(value="param1", required=true) String param1,
    @RequestParam(value="param2", required=false) String param2){
.......
}
 
@PathParam:這個註解是和spring的pathVariable是同樣的,也是基於模板的,可是這個是jboss包下面的一個實現,上面的是spring的一個實現,都要導包
@QueryParam:@QueryParam 是 JAX-RS 原本就提供的,和Spring的RequestParam做用一致

 

d.功能類註解

引用配置

@Import註解是引入帶有@Configuration的java類。

@ImportResource是引入spring配置文件.xml

自動掃描註解

@ComponentScan: 掃描指定包下的Component(@Componment,@Configuration,@Service 等等)

緩存

@EnableCaching: 管理Cache對象註解是spring framework中的註解驅動的緩存管理功能。自spring版本3.1起加入了該註解。若是你使用了這個註解,那麼你就不須要在XML文件中配置cache manager了,等價於 <cache:annotation-driven/>

@Cacheable 的做用 主要針對方法配置,可以根據方法的請求參數對其結果進行緩存。@Cacheable能夠標記在一個方法上(該方法是支持緩存的),也能夠標記在一個類上(該類全部的方法都是支持緩存的)。

事務
@Transactional能夠在service類或方法前加上@Transactional,在service類上聲明@Transactional,service全部方法須要事務管理。每個業務方法開始時都會打開一個事務。

AOP

@Aspect(切面): 一般是一個類的註解,裏面能夠定義切入點和通知

@Pointcut(切入點): JoinPoint的集合,是程序中須要注入Advice的位置的集合,指明Advice要在什麼樣的條件下才能被觸發,在程序中主要體現爲書寫切入點表達式。

定時任務
@Scheduled:定時任務

 

@ComponentScan
  掃描com.jdon.springboot2的整個父樹。@ComponentScan(「com.jdon.springboot2」)   
  使用數組定義兩個特定的組件掃描。@ComponentScan({「com.jdon.springboot2.abc」,」com.jdon.springboot2.efg」})

@Transactional

 

@Transactional 能夠做用於接口、接口方法、類以及類方法上。看成用於類上時,該類的全部 public 方法將都具備該類型的事務屬性,也能夠在方法級別使用該標註來覆蓋類級別的定義。

 雖然 @Transactional 註解能夠做用於接口、接口方法、類以及類方法上,可是 Spring 建議不要在接口或者接口方法上使用該註解,由於這隻有在使用基於接口的代理時它纔會生效。

@Transactional 註解應該只被應用到 public 方法上,這是由 Spring AOP 的本質決定的。若是你在 protected、private 或者默承認見性的方法上使用 @Transactional 註解,這將被忽略,也不會拋出任何異常。

 默認狀況下,只有來自外部的方法調用纔會被AOP代理捕獲,也就是,類內部方法調用本類內部的其餘方法並不會引發事務行爲,即便被調用方法使用@Transactional註解進行修飾。

@Aspect

Advice(通知、切面): 某個鏈接點所採用的處理邏輯,也就是向鏈接點注入的代碼, AOP在特定的切入點上執行的加強處理。
  1.1 @Before: 標識一個前置加強方法,至關於BeforeAdvice的功能.   1.2 @After: final加強,無論是拋出異常或者正常退出都會執行.   1.3 @AfterReturning: 後置加強,似於AfterReturningAdvice, 方法正常退出時執行.   1.4 @AfterThrowing: 異常拋出加強,至關於ThrowsAdvice.   1.5 @Around: 環繞加強,至關於MethodInterceptor. JointPoint(鏈接點):程序運行中的某個階段點,好比方法的調用、異常的拋出等。 Pointcut(切入點): JoinPoint的集合,是程序中須要注入Advice的位置的集合,指明Advice要在什麼樣的條件下才能被觸發,在程序中主要體現爲書寫切入點表達式。 Advisor(加強): 是PointCut和Advice的綜合體,完整描述了一個advice將會在pointcut所定義的位置被觸發。 @Aspect(切面): 一般是一個類的註解,裏面能夠定義切入點和通知 AOP Proxy:AOP框架建立的對象,代理就是目標對象的增強。Spring中的AOP代理可使JDK動態代理,也能夠是CGLIB代理,前者基於接口,後者基於子類。

 

@Scheduled
  在啓動類上面加上 @EnableScheduling 註解便可開啓定時任務
  @EnableScheduling
  @SpringBootApplication
    public class SchedulingApplication {

        public static void main(String[] args) {
            SpringApplication.run(SchedulingApplication.class, args);
        }
    }
     

    @Scheduled(fixedDelay = 1000 * 10,initialDelay=1000*15)
    public void Task() { 
     
    }

    @Scheduled(fixedRate=2000):上一次開始執行時間點後2秒再次執行;
    @Scheduled(fixedDelay=2000):上一次執行完畢時間點後2秒再次執行;
    @Scheduled(initialDelay=1000, fixedDelay=2000):第一次延遲1秒執行,而後在上一次執行完畢時間點後2秒再次執行;
    @Scheduled(cron="* * * * * ?"):按cron規則執行。


    "0 0 10,14,16 * * ?" 天天上午10點,下午2點,4點 
    "0 0/30 9-17 * * ?"   朝九晚五工做時間內每半小時
    "0 0 12 ? * WED" 表示每一個星期三中午12點
    "0 0 12 * * ?" 天天中午12點觸發
    "0 * 14 * * ?" 在天天下午2點到下午2:59期間的每1分鐘觸發
    "0 0/5 14 * * ?" 在天天下午2點到下午2:55期間的每5分鐘觸發
    "0 0/5 14,18 * * ?" 在天天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發
    "0 0-5 14 * * ?" 在天天下午2點到下午2:05期間的每1分鐘觸發
    "0 10,44 14 ? 3 WED" 每一年三月的星期三的下午2:10和2:44觸發
    "0 15 10 ? * MON-FRI" 週一至週五的上午10:15觸發
    "0 15 10 15 * ?" 每個月15日上午10:15觸發
    "0 15 10 L * ?" 每個月最後一日的上午10:15觸發
    "0 15 10 ? * 6L" 每個月的最後一個星期五上午10:15觸發
    "0 15 10 ? * 6L 20014-20018" 2014年至2018年的每個月的最後一個星期五上午10:15觸發
    "0 15 10 ? * 6#3" 每個月的第三個星期五上午10:15觸發
    "0 15 10 ? * *" 天天上午10:15觸發
    "0 15 10 * * ?" 天天上午10:15觸發
    "0 15 10 * * ? *" 天天上午10:15觸發
    "0 15 10 * * ? 2017" 2017年的天天上午10:15觸發
    
    原文連接:https://blog.csdn.net/LDY1016/article/details/84326199

 

5.2 配置方式

spring的三種方式,

  1. xml文件配置、

  2. 註解配置:隱式的bean發現機制和自動裝配(@Component @Resource @Autowire @ComponentScan)和使用

  3. Java代碼裝配bean(@Configuration, @Bean)進行配置。

1、Explicit configuration in XML:顯示的XML配置。
    優勢:
         1)XML配置方式進一步下降了耦合,使得應用更加容易擴展,即便對配置文件進一步修改也不須要工程進行修改和從新編譯。
         2)在處理大的業務量的時候,用XML配置應該更加好一些。
    缺點:
         1)配置文件讀取和解析須要花費必定的時間,配置文件過多的時候難以管理。
         2)沒法對配置的正確性進行校驗,增長了測試難度。
    舉個例子:
        1、配置application.xml文件(名字隨意)
        二、聲明命名空間   xmlns="http://www.springframework.org/schema/beans 
        3、配置bean
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
         
            <bean id="user" class="ioc.User"/>
            
        </beans>
 

2、Explicit configuration in Java:顯示的JavaConfig,基於java類配置。
    JavaConfig is the preferred option for explicit configuration
because it’s more powerful, type-safe, and refactor-friendly.

    優勢:
        1)在class文件中,下降維護成本。
        2)不須要第三方解析工具。
        3)編輯期就能夠檢驗正確性,提升開發效率。

    缺點:
        1)配置代碼過多時,直接影響代碼質量,對於代碼的簡潔度有影響。
        2)業務類之間的關係不如XML配置那樣容易把握。
        3)若是須要修改配置,則要從新編譯整個工程。
    
    舉個例子:
         1)在標註了@Configuration的java類中,經過在類方法標註@Bean定義一個Bean。
        2)經過在成員變量或者方法入參處標註@Autowired按類型匹配注入,也可使用@Qualifier按名稱配置注入。
         
         @Configuration 
          public class Conf {   
              @Scope(「prototype」)   
              @Bean(「loginUserDao」)   
              public LoginUserDao loginUserDao() {   
                return new LoginUserDao();   
             }   
        }   

3、Implicit bean discovery and automatic wiring:隱式的bean掃描,基於java註解配置,自動注入。
   
    優勢:
        1)在class文件中,下降維護成本。
        2)不須要第三方解析工具,利用java反射機制。
        3)編輯期就能夠檢驗正確性,提升開發效率。
    
    缺點:
        1)若是須要對annotation進行修改,那麼要從新編譯整個工程。
        2)業務類之間的關係不如XML配置那樣容易把握。
        3)若是在程序中annotation比較多,直接影響代碼質量,對於代碼的簡潔度有影響。
        4)符合條件的多個bean注入時,spring不知道如何選擇,會有異常NoUniqueBeanDefinitionException。

    舉個例子:
        1)@Component:標註一個普通的Spring Bean類
        2)在方法處經過@Autowired使方法入參綁定Bean,而後在方法中經過代碼進行注入。

        @Scope(「prototype」)   
        @Lazy(true)  
        @Component(「loginUserDao」)  
        public class LoginUserDao {  }   

ps:
這三種方式均可以將bean交給Spring管理,那麼應該如何選擇呢? 

     根據不一樣方式的優缺點,如今的企業開發通常採用以下方式:

     一、自定義聲明的類(非第三方),採用註解的方式。

     二、對於第三方類,採用XML或者JavaConfig的方式。

    因爲SpringBoot的出現,在無配置化的趨勢下,XML配置逐漸被JavaConfig所取代,由於咱們在建立類的同時可能還要作不少事情,這是XML不發知足的。SpringBoot推薦使用JavaConfig配置。

 

5.3 自動裝配

spring從兩個角度來實現自動化裝配:

  1.組件掃描(component scanning):spring會自動發現應用上下文所建立的bean。

  2.自動裝配(autowiring):spring自動知足spring之間的依賴。

Spring提供了 五種自動裝配的類型

  ①no:顯示指明不使用Spring的自動裝配功能

  ②byName:根據屬性和組件的名稱匹配關係來實現bean的自動裝配

  ③byType:根據屬性和組件的類型匹配關係來實現bean的自動裝配,有多個適合類型的對象時裝配失敗

  ④constructor:與byType相似是根據類型自動裝配,可是要求待裝配的bean有相應的構造函數

  ⑤autodetect: 自動檢測,利用Spring的自省機制判斷使用byType或是constructor裝配

3種方式:

  1. 使用XML方式進行裝配

  2. 使用註解的方式進行裝配:隱式的bean發現機制和自動裝配(@Component @Resource @Autowire @ComponentScan)和使用

    @Resource 根據byName進行裝配

    @Autowire經過byType進行裝配

  3. Java代碼裝配bean(@Configuration, @Bean)進行配置。

 

5.4 四種依賴注入方式

     一、set注入(一般也叫屬性注入):(userDao注入到UserServiceImpl中)

     二、構造函數注入

     三、接口注入(這個如今基本不用)

     四、註解注入(@Autowire) (@Component,@Service,@Controller等直接@Autowire

 

5.5 集合屬性配置方式

集合的注入都是給<property>添加子標籤

數組:<array>
List:<list>
Set:<set>
Map:<map> ,map存放k/v 鍵值對,使用<entry>描述
Properties:<props>  <prop key=""></prop>  

普通數據:<value>
引用數據:<ref>
http://www.javashuo.com/article/p-oanjlpvh-cs.html

 

5.6 內部Bean

1. 當一個bean僅被用做另外一個bean的屬性時,它能被聲明爲一個內部bean,只能經過該類實例化。
2. 爲了定義inner bean,在Spring 的 基於XML的 配置元數據中,能夠在 <property/><constructor-arg/> 元素內使用<bean/> 元素,
3. 內部bean一般是匿名的,它們的Scope通常是prototype。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="person2" class="com.itdjx.spring.dependency.injection.Person">
        <property name="name" value="李玉"/>
        <property name="age" value="23"/>
        <property name="sex" value="女"/>
        <property name="car" >
            <bean class="com.itdjx.spring.dependency.injection.Car">
                <constructor-arg value="Ferrari" index="0"/>
                <constructor-arg value="Italy" index="1"/>
                <constructor-arg value="22500000" type="double"/>
            </bean>
        </property>
    </bean>
</beans>

參考:
https://www.jianshu.com/p/3ce23a7b096a
Spring中的內部Bean

 

六. Spring Context初始化流程

 

https://zhuanlan.zhihu.com/p/59327709

  圖中左上角是三種類型的context,xml配置方式的context、springboot的context和web服務的context。

  不論哪一種context,建立後都會調用到AbstractApplicationContext類的refresh方法,這個方法是咱們要重點分析的。

  refresh方法中,操做共分13步:

  1. prepareRefresh(); 對刷新進行準備,包括設置開始時間,設置激活狀態,初始化Context中的佔位符,子類根據其需求執行具體準備工做,然後再由父類驗證必要參數
  2. obtianFreshBeanFactory(); 刷新並獲取內部的BeanFactory對象
  3. prepareBeanFactory(beanFactory); 對BeanFactory進行準備工做,包括設置類加載器和後置處理器,配置不能自動裝配的類型,註冊默認的環境Bean
  4. postProcessBeanFactory(beanFactory); 爲Context的子類提供後置處理BeanFactory的擴展能力,如想在bean定義加載完成後,開始初始化上下文以前進行邏輯操做,可重寫這個方法
  5. invokeBeanFactoryPostProcessors(beanFactory); 執行Context中註冊的BeanFactory後置處理器,有兩張處理器,一種是能夠註冊Bean的後置處理器,一種的針對BeanFactory的後置處理器,執行順序是先按優先級執行註冊Bean的後置處理器,然後再按優先級執行鍼對BeanFactory的後置處理器SpringBoot中會進行註解Bean的解析,由ConfigurationClassPostProcessor觸發,由ClassPathDefinitionScanner解析,並註冊到BeanFactory
  6. registerBeanFactoryProcessor(beanFactory(); 按優先級順序在BeanFactory中註冊Bean的後置處理器,Bean處理器可在Bean的初始化先後處理
  7. initMessageSource();初始化消息源,消息源用於支持消息的國際化
  8. initApplicationEventMuticaster();初始化應用事件廣播器,用於向ApplicationListener通知各類應用產生的事件,標準的觀察者模型
  9. onRefresh(); 用於子類的擴展步驟,用於特定的Context子類初始化其餘的Bean
  10. registerListeners(); 把實現了ApplicationListener的類註冊到廣播器,並對廣播其中早期沒有廣播的事件進行通知
  11. finishBeanFactoryInitialization(beanFactory); 凍結全部Bean描述信息的修改,實例化非延遲加載的單例Bean
  12. finishRefresh(); 完成上下文的刷新工做,調用LifecycleProcessor.onRefresh(),以及發佈ContextRefreshedEvent事件
  13. resetCommonCaches(); 在finally中執行該步驟,重置公共的緩存,如ReflectionUtils中的緩存,AnnotationUtils等

   更詳細可見:SpringBoot源碼分析之Spring容器的refresh過程

 

七. Spring中bean的生命週期

Spring中bean的生命週期

第1步:調用bean的構造方法建立bean;

第2步:經過反射調用setter方法進行屬性的依賴注入;

第3步:若是實現BeanNameAware接口的話,會設置bean的name;

第4步:若是實現了BeanFactoryAware,會把bean factory設置給bean;

第5步:若是實現了ApplicationContextAware,會給bean設置ApplictionContext;

第6步:若是實現了BeanPostProcessor接口,則執行前置處理方法;

第7步:實現了InitializingBean接口的話,執行afterPropertiesSet方法;

第8步:執行自定義的init方法;

第9步:執行BeanPostProcessor接口的後置處理方法。

這時,就完成了bean的建立過程。

在使用完bean須要銷燬時,會先執行DisposableBean接口的destroy方法,而後在執行自定義的destroy方法。

這部分也建議閱讀源碼加深理解。

 

八. Spring擴展接口

 

對spring進行定製化功能擴展時,能夠選擇以下一些擴展點:

▌1.BeanFactoryPostProcessor

是beanFactory後置處理器,支持在bean factory標準初始化完成後,對bean factory進行一些額外處理。在講context初始化流程時介紹過,這時全部的bean的描述信息已經加載完畢,可是尚未進行bean初始化。例如前面提到的PropertyPlaceholderConfigurer,就是在這個擴展點上對bean屬性中的佔位符進行替換。

▌2.BeanDefinitionRegistryPostProcessor

它擴展自BeanFactoryPostProcessor,在執行BeanFactoryPostProcessor的功能前,提供了能夠添加bean definition的能力,容許在初始化通常bean前,註冊額外的bean。例如能夠在這裏根據bean的scope建立一個新的代理bean。

▌3.BeanPostProcessor

提供了在bean初始化以前和以後插入自定義邏輯的能力。與BeanFactoryPostProcessor的區別是處理的對象不一樣,BeanFactoryPostProcessor是對beanfactory進行處理,BeanPostProcessor是對bean進行處理。

注:上面這三個擴展點,能夠經過實現Ordered和PriorityOrdered接口來指定執行順序。實現PriorityOrdered接口的processor會先於實現Ordered接口的執行。

▌4.ApplicationContextAware

能夠得到ApplicationContext及其中的bean,當須要在代碼中動態獲取bean時,能夠經過實現這個接口來實現。

▌5.InitializingBean

能夠在bean初始化完成,全部屬性設置完成後執行特定邏輯,例如對自動裝配對屬性進行驗證等等。

▌6.DisposableBean

用於在bean被銷燬前執行特定的邏輯,例如作一些回收工做等。

▌7.ApplicationListener

用來監聽spring的標準應用事件或者自定義事件。

 

參考網址

  1. 官網:https://spring.io/projects/spring-framework
  2. 百度百科:https://baike.baidu.com/item/spring/85061?fr=aladdin#7
  3. Spring中文文檔-第一部分
  4. 幾種placeholder替換項目參數的方法比較
  5. SpringBoot源碼分析之Spring容器的refresh過程
相關文章
相關標籤/搜索