1. 程式人生 > >(一)Spring框架內容總結

(一)Spring框架內容總結

Spring致力於提供一種方法管理你的業務物件。在大量Java EE的應用中,隨處可見Spring。今天我將簡單的介紹一下Spring這個框架。

本文適合讀者:

  • 想學Spring的Java開發者
  • 剛用Spring不久的人

Why

為什麼要使用Spring?

Spring主要兩個有功能為我們的業務物件管理提供了非常便捷的方法:

  • DI(Dependency Injection,依賴注入)
  • AOP(Aspect Oriented Programming,面向切面程式設計)

Java Bean

每一個類實現了Bean的規範才可以由Spring來接管,那麼Bean的規範是什麼呢?

  • 必須是個公有(public)類
  • 有無參建構函式
  • 用公共方法暴露內部成員屬性(getter,setter)

實現這樣規範的類,被稱為Java Bean。即是一種可重用的元件。

DI-依賴注入

簡單來說,一個系統中可能會有成千上萬個物件。如果要手工維護它們之間的關係,這是不可想象的。我們可以在Spring的XML檔案描述它們之間的關係,由Spring自動來注入它們——比如A類的例項需要B類的例項作為引數set進去。

AOP-面向切面程式設計

就以日誌系統為例。在執行某個操作前後都需要輸出日誌,如果手工加程式碼,那簡直太可怕了。而且等程式碼龐大起來,也是非常難維護的一種情況。這裡就需要面向切面來程式設計

How

關於Bean

Bean的生命週期

如你所見,在bean準備就緒之前,bean工廠執行了若干啟動步驟。我們對圖進行詳細描述:

  1. Spring對bean進行例項化;
  2. Spring將值和bean的引用注入到bean對應的屬性中;
  3. 如果bean實現了BeanNameAware介面,Spring將bean的ID傳遞給setBean-Name()方法;
  4. 如果bean實現了BeanFactoryAware介面,Spring將呼叫setBeanFactory()方法,將BeanFactory容器例項傳入;
  5. 如果bean實現了ApplicationContextAware介面,Spring將呼叫setApplicationContext()方法,將bean所在的應用上下文的引用傳入進來;
  6. 如果bean實現了BeanPostProcessor介面,Spring將呼叫它們的post-ProcessBeforeInitialization()方法;
  7. 如果bean實現了InitializingBean介面,Spring將呼叫它們的after-PropertiesSet()方法。類似地,如果bean使用init-method聲明瞭初始化方法,該方法也會被呼叫;
  8. 如果bean實現了BeanPostProcessor介面,Spring將呼叫它們的post-ProcessAfterInitialization()方法;
  9. 此時,bean已經準備就緒,可以被應用程式使用了,它們將一直駐留在應用上下文中,直到該應用上下文被銷燬
  10. 如果bean實現了DisposableBean介面,Spring將呼叫它的destroy()介面方法。同樣,如果bean使用destroy-method聲明瞭銷燬方法,該方法也會被呼叫。

Bean的作用域【scope=“ ”

Spring定義了多種Bean作用域,可以基於這些作用域建立bean,包括:

  • 單例(Singleton):在整個應用中,只建立bean的一個例項。
  • 原型(Prototype):每次注入或者通過Spring應用上下文獲取的時候,都會建立一個新的bean例項。
  • 會話(Session):在Web應用中,為每個會話建立一個bean例項。
  • 請求(Rquest):在Web應用中,為每個請求建立一個bean例項。

在程式碼裡看起來是這樣的:

12@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)public class MyIsBean{...}

XML版本:

1234<bean id="BEANID"class "net.itxm.beans"scope="prototype">

在預設情況下,Spring應用上下文中所有bean都是作為以單例(singleton)的形式建立的。也就是說,不管給定的一個bean被注入到其他bean多少次,每次所注入的都是同一個例項。

在大多數情況下,單例bean是很理想的方案。初始化和垃圾回收物件例項所帶來的成本只留給一些小規模任務,在這些任務中,讓物件保持無狀態並且在應用中反覆重用這些物件可能並不合理。

有時候,可能會發現,你所使用的類是易變的(mutable),它們會保持一些狀態,因此重用是不安全的。在這種情況下,將class宣告為單例的bean就不是什麼好主意了,因為物件會被汙染,稍後重用的時候會出現意想不到的問題。

宣告Bean

以下是宣告Bean的註解:

  • @Component 元件,沒有明確的角色
  • @Service 在業務邏輯層使用
  • @Repository 在資料訪問層使用
  • @Controller 在展現層使用(MVC -> Spring MVC)使用
  • 在這裡,可以指定bean的id名:Component(“yourBeanName”)
  • 同時,Spring支援將@Named作為@Component註解的替代方案。兩者之間有一些細微的差異,但是在大多數場景中,它們是可以互相替換的。

關於依賴注入

注入Bean的註解

@Autowired Spring提供的註解

不僅僅是物件,還有在構造器上,還能用在屬性的Setter方法上。

不管是構造器、Setter方法還是其他的方法,Spring都會嘗試滿足方法引數上所宣告的依賴。假如有且只有一個bean匹配依賴需求的話,那麼這個bean將會被裝配進來。

如果沒有匹配的bean,那麼在應用上下文建立的時候,Spring會丟擲一個異常。為了避免異常的出現,你可以將@Autowired的required屬性設定為false。

將required屬性設定為false時,Spring會嘗試執行自動裝配,但是如果沒有匹配的bean的話,Spring將會讓這個bean處於未裝配的狀態。但是,把required屬性設定為false時,你需要謹慎對待。如果在你的程式碼中沒有進行null檢查的話,這個處於未裝配狀態的屬性有可能會出現NullPointerException。

@Inject註解來源於Java依賴注入規範,該規範同時還為我們定義了@Named註解。在自動裝配中,Spring同時支援@Inject和@Autowired。儘管@Inject和@Autowired之間有著一些細微的差別,但是在大多數場景下,它們都是可以互相替換的。

@Autowired 是最常見的註解之一,但在老專案中,你可能會看到這些註解,它們的作用和@Autowired 相近:

  • @Inject 是JSR-330提供的註解
  • @Resource 是JSR-250提供的註解

條件化的Bean

假設你希望一個或多個bean只有在應用的類路徑下包含特定的庫時才建立。或者我們希望某個bean只有當另外某個特定的bean也聲明瞭之後才會建立。我們還可能要求只有某個特定的環境變數設定之後,才會建立某個bean。

在Spring 4之前,很難實現這種級別的條件化配置,但是Spring 4引入了一個新的@Conditional註解,它可以用到帶有@Bean註解的方法上。如果給定的條件計算結果為true,就會建立這個bean,否則的話,這個bean會被忽略。

通過ConditionContext,我們可以做到如下幾點:

  • 藉助getRegistry()返回的BeanDefinitionRegistry檢查bean定義;
  • 藉助getBeanFactory()返回的ConfigurableListableBeanFactory檢查bean是否存在,甚至探查bean的屬性;
  • 藉助getEnvironment()返回的Environment檢查環境變數是否存在以及它的值是什麼;
  • 讀取並探查getResourceLoader()返回的ResourceLoader所載入的資源;
  • 藉助getClassLoader()返回的ClassLoader載入並檢查類是否存在。

處理自動裝配的歧義性

標示首選的bean

在宣告bean的時候,通過將其中一個可選的bean設定為首選(primary)bean能夠避免自動裝配時的歧義性。當遇到歧義性的時候,Spring將會使用首選的bean,而不是其他可選的bean。實際上,你所宣告就是“最喜歡”的bean。

限定自動裝配的bean

設定首選bean的侷限性在於@Primary無法將可選方案的範圍限定到唯一一個無歧義性的選項中。它只能標示一個優先的可選方案。當首選bean的數量超過一個時,我們並沒有其他的方法進一步縮小可選範圍。

與之相反,Spring的限定符能夠在所有可選的bean上進行縮小範圍的操作,最終能夠達到只有一個bean滿足所規定的限制條件。如果將所有的限定符都用上後依然存在歧義性,那麼你可以繼續使用更多的限定符來縮小選擇範圍。

@Qualifier註解是使用限定符的主要方式。它可以與@Autowired和@Inject協同使用,在注入的時候指定想要注入進去的是哪個bean。例如,我們想要確保要將IceCream注入到setDessert()之中:

12345@Autowired@Qualifier("iceCream")public void setDessert(Dessert dessert){this.dessert = dessert;}

這是使用限定符的最簡單的例子。為@Qualifier註解所設定的引數就是想要注入的bean的ID。所有使用@Component註解宣告的類都會建立為bean,並且bean的ID為首字母變為小寫的類名。因此,@Qualifier(“iceCream”)指向的是元件掃描時所建立的bean,並且這個bean是IceCream類的例項。

實際上,還有一點需要補充一下。更準確地講,@Qualifier(“iceCream”)所引用的bean要具有String型別的“iceCream”作為限定符。如果沒有指定其他的限定符的話,所有的bean都會給定一個預設的限定符,這個限定符與bean的ID相同。因此,框架會將具有“iceCream”限定符的bean注入到setDessert()方法中。這恰巧就是ID為iceCream的bean,它是IceCream類在元件掃描的時候建立的。

基於預設的bean ID作為限定符是非常簡單的,但這有可能會引入一些問題。如果你重構了IceCream類,將其重新命名為Gelato的話,那此時會發生什麼情況呢?如果這樣的話,bean的ID和預設的限定符會變為gelato,這就無法匹配setDessert()方法中的限定符。自動裝配會失敗。

這裡的問題在於setDessert()方法上所指定的限定符與要注入的bean的名稱是緊耦合的。對類名稱的任意改動都會導致限定符失效。

SpringEL

  • Value實現資源的注入

Bean的初始化和銷燬

  • Java配置方式:initMethod和destoryMethod
  • 註解:@PostConstruct和@PreDestory

Profile

提供在不同的環境下使用不同的配置

啟用Profile

Spring在確定哪個profile處於啟用狀態時,需要依賴兩個獨立的屬性:spring.profiles.active和spring.profiles.default。如果設定了spring.profiles.active屬性的話,那麼它的值就會用來確定哪個profile是啟用的。但如果沒有設定spring.profiles.active屬性的話,那Spring將會查詢spring.profiles.default的值。如果spring.profiles.active和spring.profiles.default均沒有設定的話,那就沒有啟用的profile,因此只會建立那些沒有定義在profile中的bean。

使用profile進行測試

當執行整合測試時,通常會希望採用與生產環境(或者是生產環境的部分子集)相同的配置進行測試。但是,如果配置中的bean定義在了profile中,那麼在執行測試時,我們就需要有一種方式來啟用合適的profile。

Spring提供了@ActiveProfiles註解,我們可以使用它來指定執行測試時要啟用哪個profile。在整合測試時,通常想要啟用的是開發環境的profile。

比如Profile(“dev”)

Application Event

使用Application Event可以做到Bean與Bean之間的通訊

Spring的事件需要遵循如下流程:

  • 自定義事件,整合ApplicationEvent
  • 定義事件監聽器,實現ApplicationListener
  • 使用容器釋出事件

關於AOP

名詞介紹

通知(Advice)

通知定義了切面是什麼以及何時使用。除了描述切面要完成的工作,通知還解決了何時執行這個工作的問題。它應該應用在某個方法被呼叫之前?之後?之前和之後都呼叫?還是隻在方法丟擲異常時呼叫?

Spring切面可以應用5種類型的通知:

  • 前置通知(Before):在目標方法被呼叫之前呼叫通知功能;
  • 後置通知(After):在目標方法完成之後呼叫通知,此時不會關心方法的輸出是什麼;
  • 返回通知(After-returning):在目標方法成功執行之後呼叫通知;
  • 異常通知(After-throwing):在目標方法丟擲異常後呼叫通知;
  • 環繞通知(Around):通知包裹了被通知的方法,在被通知的方法呼叫之前和呼叫之後執行自定義的行為。

對應註解:

注  解通  知
@After通知方法會在目標方法返回或丟擲異常後呼叫
@AfterReturning通知方法會在目標方法返回後呼叫
@AfterThrowing通知方法會在目標方法丟擲異常後呼叫
@Around通知方法會將目標方法封裝起來
@Before通知方法會在目標方法呼叫之前執行

連線點(Join point)

連線點是在應用執行過程中能夠插入切面的一個點。這個點可以是呼叫方法時、丟擲異常時、甚至修改一個欄位時。切面程式碼可以利用這些點插入到應用的正常流程之中,並新增新的行為。

切點(Pointcut)

如果說通知定義了切面的“什麼”和“何時”的話,那麼切點就定義了“何處” 。切點的定義會匹配通知所要織入的一個或多個連線點。我們通常使用明確的類和方法名稱,或是利用正則表示式定義所匹配的類和方法名稱來指定這些切點。有些AOP框架允許我們建立動態的切點,可以根據執行時的決策(比如方法的引數值)來決定是否應用通知。

切面(Aspect)

通知+切點=切面

引入(Introduction)

引入允許我們向現有的類新增新方法或屬性

織入(Weaving)

織入是把切面應用到目標物件並建立新的代理物件的過程。切面在指定的連線點被織入到目標物件中。在目標物件的生命週期裡有多個點可以進行織入:

  • 編譯期:切面在目標類編譯時被織入。這種方式需要特殊的編譯器。AspectJ的織入編譯器就是以這種方式織入切面的。
  • 類載入期:切面在目標類載入到JVM時被織入。這種方式需要特殊的類載入器(ClassLoader),它可以在目標類被引入應用之前增強該目標類的位元組碼。AspectJ 5的載入時織入(load-time weaving,LTW)就支援以這種方式織入切面。
  • 執行期:切面在應用執行的某個時刻被織入。一般情況下,在織入切面時,AOP容器會為目標物件動態地建立一個代理物件。Spring AOP就是以這種方式織入切面的。
  1. 基於代理的經典Spring AOP;
  2. 純POJO切面(4.x版本需要XML配置);
  3. @AspectJ註解驅動的切面;
  4. 注入式AspectJ切面(適用於Spring各版本)。

前三種都是Spring AOP實現的變體,Spring AOP構建在動態代理基礎之上,因此,Spring對AOP的支援侷限於方法攔截。也就是說,AspectJ才是王道

另外在代理類中包裹切面,Spring在執行期把切面織入到Spring管理的bean中。如下圖所示,代理類封裝了目標類,並攔截被通知方法的呼叫,再把呼叫轉發給真正的目標bean。當代理攔截到方法呼叫時,在呼叫目標bean方法之前,會執行切面邏輯。直到應用需要被代理的bean時,Spring才建立代理物件。 如果使用的是ApplicationContext的話,在ApplicationContext從BeanFactory中載入所有bean的時候,Spring才會建立被代理的物件。因為Spring執行時才建立代理物件,所以我們不需要特殊的編譯器來織入Spring AOP的切面。

例子

123public interface Performance(){

相關推薦

Spring框架內容總結

Spring致力於提供一種方法管理你的業務物件。在大量Java EE的應用中,隨處可見Spring。今天我將簡單的介紹一下Spring這個框架。本文適合讀者:想學Spring的Java開發者剛用Spring不久的人Why為什麼要使用Spring?Spring主要兩個有功能為我

Spring框架學習之路——Spring框架基本介紹

Spring的出現是為了取代EJB(Enterprise JavaBean)的臃腫、低效、脫離現實的缺點。Spring致力於J2EE應用的各層(表現層、業務層、持久層)的解決方案,Spring是企業應用開發的“一站式”選擇。 1.Spring定義: Spring是分層的J

【Nginx實戰】——Nginx要點內容總結

解決問題 單臺伺服器已經無法承擔大量使用者的併發訪問,必須採用多臺伺服器協同工作,以提高計算機系統的處理能力和計算強度(叢集),滿足當前業務量的需求。如何完成同樣功能的多個網路裝置之間實現合理的業務量分配——負載均衡。 負載均衡策略/演算法

OpenGL在MFC中的使用總結——基本框架

palette 接受 white 要求 無效 結構 del 一次 是你 項目中要畫3D顯示的模型,於是要用到OpenGL,加上是在MFC中,並且是在MFC中的ActiveX中使用。再並且鑒於他們程序主框架的設定。常規的方法還不一定能實現。所以還是查過不少資料,在此一一總

Java Spring MVC專案搭建——Spring MVC框架整合

轉自:https://www.cnblogs.com/eczhou/p/6287852.html 1、Java JDK及Tomcat安裝 我這裡安裝的是JDK 1.8 及 Tomcat 8,安裝步驟詳見:http://www.cnblogs.com/eczhou/p/6285248.html

spring框架——Spring核心框架體系結構jar包引用分析

很多人都在用spring開發java專案,普通新增lib目錄拷貝jar包,或者建立maven專案時,配置maven依賴的時候並不能明確要配置哪些spring的jar,經常是胡亂新增一堆,編譯或執行報錯就繼續配置jar依賴,導致spring依賴混亂,甚至下一次建立相同型別的工程時也不知道要配置哪些sp

Java框架學習_SpringSpring相關的概念、Spring的配置和屬性注入

學習java框架的路線定為Spring + Mybatis + SpringMVC,即SSM,下面先開始經典的Spring的學習 Spring的開發包:spring-framework-4.2.4.RELEASE-dist 1、Spring相關的概念: Spring:ful

Spring security 架構框架-Component、Service、Filter分析

1.spring security 認證和授權流程 常見認證和授權流程可以分成: A user is prompted to log in with a username and password (使用者用賬密碼登入) The system (successfully) verifies that th

Java安全框架Spring Security

文章主要分三部分 1、Spring Security的架構及核心元件:(1)認證;(2)許可權攔截;(3)資料庫管理;(4)許可權快取;(5)自定義決策; 2、環境搭建與使用,使用當前熱門的Spring Boot來搭建環境,結合專案中實際的例子來做幾個Case; 3、Spring Security的優缺點總結

spring入門

util value app ng- pub final class test frame 一、applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="htt

Spring Cloud— 子項目、未來 整合介紹

springcloud 電子商務 子項目 雲架構 微服務 Spring Cloud是一系列框架的有序集合。利用Spring Boot的開發模式簡化了分布式系統基礎設施的開發,如服務發現、註冊、配置中心、消息總線、負載均衡、斷路器、數據監控等(這裏只簡單的列了一部分),都可以用Spring

數據庫設計概念、內容、步驟和參考資料

及其 用戶 各類 都沒有 處理 步驟 有效 database 意思 概念 百度百科對數據庫設計的給了如下的描述: 數據庫設計(Database Design)是指對於一個給定的應用環境,構造最優的數據庫模式,建立數據庫及其應用系統,使之能夠有效地存儲數據,滿足各種用戶的應用

SSM應用--Spring入門

得到 執行 主動 關系 ted img 我們 ica http Spring是什麽   Spring是一個框架;   Spring是一個容器框架;   Spring用於管理bean(Java類),並維護bean(Java類)之間的關系;   容器框架:整個web都屬

spring cloud實戰與思考 spring config全局配置方案設計

功能 IE 基於 比較 此外 fig eureka 搜索 地址 “spring cloud”的配置中心工具“spring cloud config”提供了分布式系統配置文件集中管理解決方案。該工具功能強大,實現也很簡單。網上可以搜索到很多開發教程和用例。本文並不是分享“

spring cloud架構整合-springcloud簡介

電子商務 雲服務 spring cloud 架構 互聯網 Spring Cloud是一系列框架的有序集合。利用Spring Boot的開發模式簡化了分布式系統基礎設施的開發,都可以用Spring Boot的開發風格做到一鍵啟動和部署。Spring Cloud將目前比較成熟、經得起實際考驗的

python selenium系列框架介紹及安裝

row pre ive AS baidu mar 在操作 pan 但是 一 selenium是什麽?引用百度百科的介紹selenium的一段話:“Selenium 是一個用於Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的

SpringBoot學習——Spring的發展

spa java類 配置文件 實踐 項目 ice bsp 配置 學習 一、Spring1.x時代   在Spring1.x時代,都是通過xml文件配置bean,隨著項目的不斷擴大,需要將xml配置分放到不同的配置文件中,需要頻繁的在Java類和xml配置文件中切換。 二

Spring Boot—— Spring Boot 入門

mpi cti 準備 enc 標簽 martin 發的 nbsp oot 1、Spring Boot 簡介 簡化Spring應用開發的一個框架; 整個Spring技術棧的一個大整合; J2EE開發的一站式解決方案; 2、微服務 微服務:架構風格(服務微化) 一個應用

Spring MVC簡介

spa 渲染 pin 行處理 根據 jstl 處理器 類的屬性 簡單 一、概述 Spring web mvc和Struts2都屬於表現層的框架,它是Spring框架的一部分。Spring Web MVC是一種基於Java的實現了Web MVC設計模式的請求驅動類型的輕量級W

SpringBoot 2.X 學習筆記Spring Boot HelloWorld

pre urn art release ret XML tap tro 簡化 Spring Boot HelloWorld 實現一個最簡單的功能:瀏覽器發送hello請求,服務器接受請求並處理,響應Hello World字符串; 1、創建一個maven工程;(jar) 2、