亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

閑言碎語-逐步了解Spring

 更新時間:2017年11月23日 09:51:15   作者:Wung  
這篇文章主要介紹了閑言碎語-逐步了解Spring,涉及Spring的誕生,簡介,作用等相關內容,具有一定參考價值,需要的朋友可以了解下。

WHY

在誕生之初,創(chuàng)建Spring的主要目的是用來替代更加重量級的企業(yè)級Java技術,尤其是EJB。相對于EJB來說,Spring提供了更加輕量級和簡單的編程模型。

WHAT

Spring是一個開源框架,最早由RodJohnson創(chuàng)建,Spring是為了解決企業(yè)級應用開發(fā)的復雜性而創(chuàng)建的,使用Spring可以讓簡單的JavaBean實現(xiàn)之前只有EJB才能完成的事情。Spring不僅僅限于服務端的開發(fā),任何Java應用都能在簡單性、可測試性和松耦合等方面從Spring中獲益。

如今Spring在移動開發(fā)、社交API集成、NoSQL數(shù)據庫、云計算及大數(shù)據方面都在涉足。隨著時間的推移EJB也采用了依賴注入(DependencyInjection,DI)和面向切面編程(Aspect-OrientedProgramming,AOP)的理念??傊?,Spring最根本的使命就是簡化Java開發(fā)

HOW

為了降低Java開發(fā)的復雜性,Spring采取了4鐘關鍵策略

基于POJO的輕量級和最小侵入性編程通過依賴注入和面向接口實現(xiàn)松耦合

基于切面和慣例進行聲明式編程通過切面和模板減少樣式代碼

POJO潛能

很多框架通過強迫應用繼承它們的類或實現(xiàn)它們的接口從而導致應用與框架綁定在一起,這就是侵入性編程,導致無法復用代碼塊。Spring竭力避免因自身的API而弄亂你的應用代碼,在基于Spring構建的應用程序中,他的類通常沒有任何痕跡表明你使用了Spring

public class HelloWorldBean {
  public String sayHello(){
    return "Hello World";
  }
}

以上的實例代碼表示一個很簡單普通的Java類(POJO),你看不出來他是一個Spring組件,Spring的非侵入式編程體現(xiàn)在這個類在Spring應用和非Spring應用中都可以發(fā)揮作用。僅僅這么一段代碼并沒有能實際體現(xiàn)Spring功能,還需要后面的知識。
依賴注入(將自身依賴的類注入的自身)

依賴注入這個此在Spring中并不是這么高大上,盡管現(xiàn)在已經演變成一項復雜的編程技巧或者設計模式理念。在Spring中可以這么理解,注入依賴。一個具有實際意義的應用都需要多個類進行相互協(xié)作來完成特定的業(yè)務邏輯。傳統(tǒng)的做法是每個對象負責管理與自己有關的對象(這個有關的對象就是Spring中表述的所依賴的對象)的引用,不過這將會導致高度耦合和代碼難以測試

考慮如下代碼

/**這個拗口的類名是作者為了擬合一個模擬的場景特地取名
 * 這個類表示營救少女的騎士
 * Created by Wung on 2016/8/25.
 */
public class DamselRescuingKnight implements Knight{
	private RescueDamselQuest quest;
	/**
   * 在它的構造函數(shù)中自行創(chuàng)建了RescueDamselQuest
   * 這使得DamselRescuingKnight和在它的構造函數(shù)中自行創(chuàng)建了RescueDamselQuest耦合在了一起
   */
	public DamselRescuingKnight(){
		this.quest = new RescueDamselQuest();
	}
	public void embarkOnQuest(){
		quest.embark();
	}
}

耦合具有兩面性,一方面,緊密耦合的代碼難以測試難以復用難以理解,并且會出現(xiàn)"打地鼠"式的BUG。另一方面,一定程度的耦合又是必要的,不同的類必須以適當?shù)姆绞竭M行交互。

問題出現(xiàn)了,那么Spring是如何解決的呢

在Spring中,通過依賴注入(DI),對象之間的依賴關系由系統(tǒng)中負責協(xié)調各對象的第三方組件在創(chuàng)建對象的時候進行設定。也就是說對象只需要管理自己內部的屬性而無需自行創(chuàng)建或者管理它們的依賴關系,依賴關系會被自動注入到需要它們的對象當中去。

/**
 * 這個騎士可以執(zhí)行各種冒險任務而不在僅僅是之前那個營救少女的任務
 * Created by Wung on 2016/8/25.
 */
public class BraveKnight implements Knight{
	private Quest quest;
	/**
   * BraveKnight沒有自行創(chuàng)建冒險類型,而是在構造的時候把冒險任務作為參數(shù)傳入
   * 這是依賴注入的方式之一:構造器注入
   */
	public BraveKnight(Quest quest){
		this.quest = quest;
	}
	public void embarkOnQuest(){
		quest.embark();
	}
}

BraveKnight沒有與任何特定的Quest實現(xiàn)發(fā)生耦合,只要某個任務實現(xiàn)了Quest接口,那么具體是哪種類型的冒險就無所謂了,這就打到了DI的目的——松耦合

如果一個對象只通過接口來表明依賴關系,那么這種依賴關系就能夠在對象本身毫不知情的情況下用不同的具體實現(xiàn)來進行替代。

那么現(xiàn)在來進行實際意義的注入

對于上面那塊代碼我們來將一個具有具體實現(xiàn)的冒險任務注入到勇敢騎士中去

/**屠龍的冒險任務(這個作者好中二阿)
 * Created by Wung on 2016/8/25.
 */
public class SlayDragonQuest implements Quest{
	private PrintStream stream;
	public SlayDragonQuest(PrintStream stream){
		this.stream = stream;
	}
	public void embark() {
		stream.print("slay the dragon");
	}
}

那么現(xiàn)在問題來了,在SlayDragonQuest中如何注入它所依賴的PrintStream對象,在BraveKnight中如何注入它所依賴的Quest對象。前面提到的Spring會將這些依賴進行集中管理,創(chuàng)建應用組件之間協(xié)作的行為通常稱為裝配(wiring)也就是注入。Spring提供了多種裝配的方式在后面會更加詳細的介紹,此處簡單介紹基于XML的裝配和基于Java注解的裝配

<!--
    這就是一個裝配的過程,將SlayDragonQuest聲明為一個bean,取名為"quest"
    因為是構造器注入所以使用constructor-arg屬性 value表示注入的值
    那么這個過程解決了之前的問題,將PrintStream對象注入到SlayDragonQuest對象中
  -->
  <bean class="impl.SlayDragonQuest" id="quest">
    <constructor-arg value="#{T(System).out}">
  </constructor-arg></bean>
 
  <!--
    這個過程同上,BraveKnight聲明為一個bean取名為"knight"(不一定使用到這個名字)
    然后BraveKnight的構造器參數(shù)要求為Quest類型此時傳入了另外一個bean的引用
    就是上面這個名字"quest"的bean的引用,此時也完成了對BraveKnight的構造器注入
   -->
  <bean class="impl.BraveKnight" id="knight">
    <constructor-arg ref="quest">
  </constructor-arg></bean>

Spring提供了基于Java的配置,可作為XML的替代方案

/**基于Java的配置文件實現(xiàn)對象的裝配
 * Created by Wung on 2016/8/26.
 */
@Configuration
public class KnightConfig {
   
  @Bean
  public Knight knight(){
    return new BraveKnight(quest());
  }
 
  @Bean
  public Quest quest(){
    return new SlayDragonQuest(System.out);
  }
}

效果是相同的,具體的解釋在下一章中詳細描述。現(xiàn)在再來回顧一下,一直說Spring會自動管理對象之間的依賴關系,那么這種管理者是什么。答案是Application Context(應用上下文),它是Spring的一種容器,可以裝載bean的定義并將它們組裝起來。Spring應用上下文全權負責對象的創(chuàng)建和組裝。實際上這個Context有好多中實現(xiàn)他們之間的區(qū)別僅僅是加載配置的方式不同,下面來看一種加載配置的方式

public class KnightMain {
 
  public static void main(String[] args){
    AnnotationConfigApplicationContext context = new
        AnnotationConfigApplicationContext(KnightConfig.class);
    //從配置文件中就可以獲取到bean的定義了
    Knight knight = context.getBean(Knight.class);
    knight.embarkOnQuest();
    context.close();
  }
 
}

應用切面

DI能夠讓相互協(xié)作的軟件組件保持松耦合,而面向切面編程允許你把遍布應用各處的功能分離出來形成可重用的組件,更詳細的說,它是促使軟件系統(tǒng)實現(xiàn)關注點奮力的一項技術。什么是關注點呢,諸如日志、事務管理、安全管理這樣的系統(tǒng)服務經常需要融入到其他自身具有業(yè)務邏輯的組件中去,那么這些系統(tǒng)服務通常就被稱為橫切關注點,因為它們會在多個地方被重用,跨越系統(tǒng)的多個組件。簡單來說,就是你把需要重用的經常會服務與各種其他組件的組件抽離出來,但是抽離出來如何使用呢,其實就是在用的時候將方法插入到需要使用的地方。但是根據這個"切面"的術語,應該表述為將重用的組件抽離出來作為一個切面,在需要使用的時候將切面橫切進組件。所以這樣就做到了核心應用不需要知道這些切面的存在,切面也不會將業(yè)務邏輯融合在核心應用中。

/**一個歌手類用來歌頌騎士也就是服務于騎士類
 * Created by Wung on 2016/8/26.
 */
public class Minstrel {
 
  private PrintStream stream;
 
  public Minstrel(PrintStream stream){
    this.stream = stream;
  }
  //在冒險之前執(zhí)行
  public void singBeforeQuest(){
    stream.print("Begin");
  }
  //在冒險之后執(zhí)行
  public void singAfterQuest(){
    stream.print("End");
  }
 
}
public class BraveKnight implements Knight{
	private Quest quest;
	private Minstrel minstrel;
	/**
   * BraveKnight沒有自行創(chuàng)建冒險類型,而是在構造的時候把冒險任務作為參數(shù)傳入
   * 這是依賴注入的方式之一:構造器注入
   */
	//  public BraveKnight(Quest quest){
	//    this.quest = quest;
	//  }
	public BraveKnight(Quest quest, Minstrel minstrel){
		this.quest = quest;
		this.minstrel = minstrel;
	}
	public void embarkOnQuest(){
		minstrel.singBeforeQuest();
		quest.embark();
		minstrel.singAfterQuest();
	}
}

這個時候這個勇敢的騎士開始執(zhí)行,但是他發(fā)現(xiàn)在他的職責中不僅僅是冒險了,現(xiàn)在竟然還要管理這個歌手要為他歌頌,然而這本身并不應該屬于這個類應該管理的。所以應用切面的思想,我們需要將這個歌手的歌頌行為抽離出來成為一個切面,在騎士冒險之前這個切面將會橫切進去執(zhí)行singBeforeQuest方法在冒險之后執(zhí)行singAfterQuest方法。那么這樣是不是就實現(xiàn)了騎士中不需要歌頌的代碼,歌手也不存在與騎士對象中,他將不僅僅贊頌騎士,也可以贊頌任何人只要別人使用這個切面切入即可

  <!-- 意思就是將上述id為minstrel的bean配置為切面實際上就是把歌手配置為切面 -->
  aspect ref="minstrel">
    <!-- 
      定義切入點,也就是在哪里會使用切面 
      expression="execution(* *.embarkOnQuest(..))
      是一種AspectJ的切點表達式語言后面會深入
      此處的意思是會在embarkOnQuest()方法處切入
      下面那個分別為前置通知和后置通知在切入點之前和之后執(zhí)行
    --> 
  </aop:after></aop:before></aop:pointcut>
</aop:</aop:config>

現(xiàn)在的情況是Minstrel仍然是獨立的一個POJO,Spring的上下文已經將他變成了一個切面了。最重要的是此時騎士完全不知道這個切面的存在,這只是一個小小的栗子,實際上可以做很多重要的事情。

使用模板消除樣式代碼

有這樣一種情況,當我們使用JDBC訪問數(shù)據庫查詢數(shù)據的時候,完整的流程需要建立連接、創(chuàng)建語句對象、處理結果集、查詢、關閉各種連接,此外還需要各種異常的捕獲,然后對于各種場景的查詢都需要如此費心費力的重復。JDBC還不僅僅是唯一這樣會有大量的樣式代碼的情況,Spring旨在通過模板封裝來消除樣式代碼,比如Spring的jdbcTemplate。

容納你的Bean

在基于Spring的應用中,你的應用對象生存于Spring容器,容器負責創(chuàng)建對象裝配對象并且管理他們的生命周期。那什么是Spring的容器呢,容器并不是只有一種,Spring自帶了多個容器實現(xiàn)。分為兩類:bean工廠,是最簡單的容器提供基本的DI支持。應用上下文比較高級提供應用框架級別的服務。大多數(shù)情況下應用上下文更加受歡迎。

應用上下文也分為多種,顯著的區(qū)別的是加載配置的方式不同

Spring的各種功能

總結

Spring是一個可以簡化開發(fā)的框架技術,核心內容是DI和AOP。

以上就是本文關于閑言碎語-逐步了解Spring的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

SpringMVC入門實例

Spring中利用配置文件和@value注入屬性值代碼詳解

Spring集成Redis詳解代碼示例

如有不足之處,歡迎留言指出。

相關文章

  • 詳解java中的四種代碼塊

    詳解java中的四種代碼塊

    這篇文章主要介紹了詳解java中的四種代碼塊,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • 實例解析如何正確使用Java數(shù)組

    實例解析如何正確使用Java數(shù)組

    同一種類型數(shù)據的集合。其實數(shù)組就是一個容器。運算的時候有很多數(shù)據參與運算,那么首先需要做的是什么下面我們就一起來看看。
    2016-07-07
  • 在idea中顯示springboot面板的方法

    在idea中顯示springboot面板的方法

    這篇文章主要介紹了在idea中顯示springboot面板的方法方便啟動調試,本文通過代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Spring中BeanFactory解析bean詳解

    Spring中BeanFactory解析bean詳解

    本篇文章主要介紹了Spring中BeanFactory解析bean詳解 ,詳細的介紹了使用BeanFactory對bean進行解析的實例,有興趣的可以了解一下。
    2017-04-04
  • Spring模塊詳解之Spring ORM和Spring Transaction詳解

    Spring模塊詳解之Spring ORM和Spring Transaction詳解

    Spring ORM 是 Spring 框架的模塊之一,旨在簡化與 JPA、Hibernate、JDO 等 ORM 工具的集成,通過提供統(tǒng)一的 API 和模板類,如 HibernateTemplate 和 JpaTemplate,Spring ORM 使開發(fā)者可以更便捷地執(zhí)行數(shù)據庫操作,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • java后端合成圖片的實現(xiàn)示例

    java后端合成圖片的實現(xiàn)示例

    本文主要介紹了java后端合成圖片的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • SPFA 算法實例講解

    SPFA 算法實例講解

    下面小編就為大家?guī)硪黄猄PFA 算法實例講解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • spring學習JdbcTemplate數(shù)據庫事務管理

    spring學習JdbcTemplate數(shù)據庫事務管理

    這篇文章主要為大家介紹了spring學習JdbcTemplate數(shù)據庫事務管理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • Spring?AOP操作的相關術語及環(huán)境準備

    Spring?AOP操作的相關術語及環(huán)境準備

    這篇文章主要為大家介紹了Spring?AOP操作的相關術語及環(huán)境準備學習,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • Mybatis分頁PageHelper插件代碼實例

    Mybatis分頁PageHelper插件代碼實例

    這篇文章主要介紹了Mybatis分頁PageHelper插件代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12

最新評論