国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring之旅第一站(不得不佩服老外...)

thekingisalwaysluc / 1612人閱讀

摘要:表示少女與緊耦合在它的構造函數中自行創建了。面向切面編程往往被定義為促使軟件系統實現關注點的分離一項技術系統由許多不同的組件組成,每個組件各負責一特定的功能。我們可以把切面想象為覆蓋在很多組件之上的一個外殼。

第1章 Spring之旅 說明

1、本文抄寫了《Spring 實戰》重點內容,參考了GitHub上的代碼

2、每個人的學習方式不一樣,但目的是一樣的,活學活用。最近一直在聽《我們不一樣》

3、本文只為記錄作為以后參考,要想真正領悟Spring的強大,請看原書。

4、代碼和筆記在這里GitHub,對你有幫助的話,歡迎點贊。

本章內容:

Spring的bean容器

介紹Spring的核心模塊

更為強大的Spring生態系統

Spring的新功能

對于Java程序員來說,這是一個很好的時代..........

Spring是Java歷史中很重要的組成部分。

在誕生之初,創建Spring的主要目的是用來代替更加重量級的企業級Java技術,尤其是EJB。相對于EJB來說,Spring提供了 更加輕量級和簡單的編程模型.它增強了簡單老式的Java對象(Plain Old Java Object POJO)的功能,使其具備了之前只有EJB和其他企業級Java規范才具有的功能。

盡管J2EE能夠趕上Spring的步伐,但Spring也沒有停止前進(我們程序員也一樣,根本停不下來...),Spring繼續在其他領域發展,移動開發、社交API集成、NoSQL數據庫、云計算以及大數據都是Spring正在涉足和創新的領域。Spring的前景會更加美好(Java也是,Java9的模塊化,只是我們需要學習的還有很多).

對于Java開發者來說,這是一個很好的時代

1.1簡化Java開發

Spring是一個開源框架,最早由Rod Johnson創建,Spring是為了解決企業級應用開發的復雜性而創建的,使用Spring可以讓簡單的JavaBean實現之前只有EJB才能完成的事,但Spring不僅僅局限于服務器端的開發,任何Java應用都能在簡單性、可測試性、和松耦合等方面從Spring中受益。

一個Sping組件可以是任何形式的POJO。所有的理念都可以追溯到Spring最恨本的使命上:簡化Java開發。

為了降低Java開發的復雜性,Spring采取了以下4種關鍵策略:

基于POJO的輕量級和最小入侵性編程;

通過依賴注入和面向接口實現松耦合;

基于切面和慣例進行聲明式編程:

通過切面和模板減少樣板代碼;

1.1.1 激發POJO的潛力

很多框架通過強迫應用繼承他們的類或實現它們的接口從而導致應用于框架綁死。

Spring避免因自身的API而弄亂你的應用代碼。Spring不會強迫你實現Spring所規范的接口或繼承Spring所規范的類,相反,在基于Spring的構建的應用中,它的類通常沒有任何跡象表明你使用了Spring。最壞的場景是,一個類或許會使用Spring注解,但它依舊是POJO。

package com.guo.spring

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

可以看到,這是一個簡單普通的Java類——POJO。沒有任何地方表明它是一個Spring組件。Spring的非侵入式編程模型意味著這個類在Spring應用和非Spring應用中都可以發揮同樣的作用。

盡管簡單,但POJO一樣可以擁有魔力,Spring賦予POJO魔力的方式之一就是通過DI來裝配它們。

1.1.2 依賴注入

依賴注入現在已經演變成一項復雜的編程技巧或設計模式的理念

任何一個有實際意義的應用都會由兩個或更多的類組成,這些類相互之間進行協作來完成特定的業務邏輯。按照傳統的做法,每個對象負責管理與自己相互協作的對象的引用(即它所依賴的對象),這就會導致高度耦合和難以測試的代碼。

/**
 * Created by guo on 20/2/2018.
 * damsel表示:少女
 */
public class DamselRescuingKnight implements Knight {
    private RescueDamselQuest quest;
    public DamselRescuingKnight ( RescueDamselQuest quest) {
        //與RescueDamselQuest緊耦合
        this.quest = new RescueDamselQuest();
    }
    @Override
    public void embarkOnQuest() {
         quest.embark();
    }
}

DamselRescueingKnight在它的構造函數中自行創建了RescueDamselQuest。這使得兩者緊緊的耦合在一起。因此極大的限制了騎士執行探險的能力。在這樣一個測試中 ,你必須保證當騎士embarkOnQuest方法被調用的時候,探險embark方法也要被調用。但是沒有一個簡單明了的方式能夠測試。

耦合具有兩面性:

緊密耦合的代碼難以岑氏,難以復用,難以理解,并且在典型的表現出"打地鼠"式的BUG特性,(修復一個bug,將會出現一個或更多的bug).

一定的程度耦合又是必須的,完全沒有耦合的代碼什么都做不了。為了完成更有實際意義的功能,不同的類必須以適當的方式進行交互,總而言之,耦合是必須的,但需要謹慎對待

通過DI,對象的依賴關系將由系統中負責協調各對象的第三方組件在創建對象的時候設定,對象無需自行創建或管理他們的依賴關系,依賴關系將被自動注入到需要它們的對象中。

依賴注入會將所依賴的關系自動交給目標對象,而不是讓對象自己去獲取依賴

BraveKnight足夠靈活可以接受任何賦予他的探險任務。

/**
 * Created by guo on 20/2/2018.
 */
public class BraveKnight implements Knight {
    public Quest quest;

    public BraveKnight(Quest quest) {          //Quest被注入進來
        this.quest = quest;
    }

    @Override
    public void embarkOnQuest() {
         quest.embark();
    }
}

不同于之前的DamselRescuingKnight,BraveKnight沒有自行創建探險任務,而是在構造的時候把探險任務作為構造參數傳入。這是依賴注入的方式之一,即構造注入(constructor injection).

需要注意的是,傳入的探險類型是一個Quest,也就是所有的探險任務都必須實現的一個接口。所以BraveKnight能夠響應RescueDamselQuest、SlayDragonQuest、MakeRoundTableRounderQuesst 等任意的Quest實現。

這里的要點是BraveKnight沒有有特定的Quest實現發生耦合。對他來說,被要求挑戰的探險任務只要實現了Quest接口,那么具體的是那種類型就無關緊要了。這就是DI帶來最大的收益——松耦合。**如果一個對象只通過接口(而不是具體的實現或初始化過程)來表明依賴關系,那么這種依賴就能夠在對象本身毫不情況的情況下,用不同的具體實例進行替換。

對依賴進行替換的一個最常用方法就是在測試的時候使用mock實現。

import static org.mockito.Mockito.*;

public class BraveKnightTest {
    @Test
    public void knightShouldEmbarkQuest() {
        Quest mockQuest = mock(Quest.class);               //創建mock Quest
        BraveKnight knight = new BraveKnight(mockQuest);   //注入mock Quest;
        knight.embarkOnQuest();
        verify(mockQuest,times(1)).embark();
    }
}

可以通過mock框架Mockito去創建一個Quest接口的mock實現。通過這個mock對象,就可以創建一個新的BraveKnight實例,并通過構造器注入到這個mock Quest。當調用embarkOnQUest方法時,你可以要求Mockito框架驗證Quest的mock實現的embark方法僅僅被調用了一次。

將Quest注入到Knight中

希望BraveKnight所進行的探險任務是殺死一只怪龍,

public class SlayDragonQuest implements Quest {
    private PrintStream stream;
    public SlayDragonQuest(PrintStream stream) {
        this.stream = stream;
    }
    @Override
    public void embark() {
        stream.println("Embarking on quest to slay the dragon!!,順便還可以學英語,一舉兩得。");
    }

SlayDragonQuest實現類Quest接口,這樣它就適合注入到BraveKnight中了,與其他入門不同的是,SlayDragonQuest沒有使用System.out.println();,而是在構造方法中請求一個更為通用的PrintStream。

創建應用組件之間協作的行為成為裝配。Spring有多種裝配Bean的方式,采用XML是一種常用的方式。
knights.xml,該文件將BraveKnight,SlayDragonQuest和PrintStream裝配到一起。



    
                                
    
         
        
    

在這里,BraveKnight和SlayDragonQuest被聲明為Spring中的bean。就BraveKnight bean來講,他在構造時傳入對SlayDragonQuest bean的引用,將其作為構造器參數。同時,SlayDragonQuest bean 的聲明使用了Spring表達式語言(Spring Expression Language),將System.out(一個PrintStream)傳入到了SlayDragonQuest的構造器中,

在SpEL中, 使用T()運算符會調用類作用域的方法和常量. 例如, 在SpEL中使用Java的Math類, 我們可以像下面的示例這樣使用T()運算符:

T(java.lang.Math)

T()運算符的結果會返回一個java.lang.Math類對象.

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

import guo.knights.BraveKnight;
import guo.knights.Knight;
import guo.knights.Quest;
import guo.knights.SlayDragonQuest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by guo on 20/2/2018.
 */
@Configuration
public class KnightConfig {
    @Bean
    public Knight knight() {
        return new BraveKnight(quest());
    }
    @Bean
    public Quest quest() {
        return new SlayDragonQuest(System.out);
    }
}

不管使用的是基于XML的配置還是基于Java的配置,DI所帶來的收益都是相同的。盡管BraveKnight依賴于Quest,但是它并不知道傳遞給它的是什么類型的Quest,與之類似,SlayDragonQuest依賴于PrintStream,但是編譯時,并不知道PrintStream長啥樣子。只有Spring通過他的配置,能夠了解這些組成部分是如何裝配起來的。這樣就可以在不改變 所依賴的類的情況下,修改依賴關系。

**接下來,我們只需要裝載XML配置文件,并把應用啟動起來。

Spring通過應用上下文(Application context) 裝載bean的定義,并把它們組裝起來。Spring應用上下文全權負責對象的創建個組裝,Spring自帶了多種應用上下文的實現,他們之間的主要區別僅僅在于如何加載配置。

因為knights.xml中的bean是使用XML文件進行配置的,所以選擇ClassPathXmlApplicationContext作為應用上下文相對是比較合適的。該類加載位于應用程序類路徑下的一個或多個Xml配置文件。

public class KnightMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("spring/knights.xml");    //加載Sprinig應用上下文
        Knight knight = context.getBean(Knight.class);                                       //獲取knight bean
        knight.embarkOnQuest();                                                              //使用knight調用方法
        context.close();                                                                     //關閉應用上下文
    }
}

輸出如下:
Embarking on quest to slay the dragon!!,順便還可以學英語,一舉兩得。

這里的main()方法基于knight.xml文件創建了spring應用上下文。隨后他調用該應用上下文獲取一個ID為knighht的bean。得到Knighht對象的引用后,只需要簡單調用embarkOnQuest方法就可以執行所賦予的探險任務了。只有knights.xml知道哪個騎士執行力那種任務。

1.1.3 應用切面

DI能夠讓相互協作的軟件組件保持松耦合,而面向切面編程(aspect-oriented programming AOP) 允許你把遍布應用各處的功能分離出來形成可重用的組件。

面向切面編程往往被定義為促使軟件系統實現關注點的分離一項技術,系統由許多不同的組件組成,每個組件各負責一特定的功能。除了實現自身核心的功能之外,這些組件還經常承擔著額外的職責。諸如日志、事務管理、和安全這樣的系統服務經常融入到自身具有核心業務邏輯的組件中。這些系統通常被稱為橫切關注點。,因此他們會跨越系統多個組件。

如果將這些關注點分散到多個組件中去,你的代碼將會帶來雙重的復雜性。

實現系統關注點功能的代碼嫁給你會重復出現在多個組件中。這意味著如果你要改變這些關注點的邏輯,必須修噶各個模塊中相關的實現。即使你把這些關注點抽象成一個獨立的模塊,其他模塊只是調用方法。但方法的調用還是會重復出現在各個模塊中。

組件會因為那些與自身核心業務無關的代碼而變得混亂。一個向地址薄增加地址條目的方法應該只關注如何添加地址。而不應該關注它是不是安全的,或者是否需要事務的支持。

AOP能使這些服務模塊化,并以聲明的方式將它們應用到它們要影響的組件中去。所造成的結果就是這些組件會具有哥哥你好的內聚性并且會更加關注自身的業務,安全不需要了解涉及系統服務所帶來的復雜性。總之AOP能確保POJO的簡單性。

我們可以把切面想象為覆蓋在很多組件之上的一個外殼。應用是由哪些實現各自業務功能模塊組成的,借助AOP,可以使用各種功能層去包裹核心業務層,,這些層以聲明的方式靈活的應用到系統中,你的核心應用甚至根本不知道他們的存在。這是一個非常強大的理念,可以將安全,事務,日志關注點與核心業務相分離。**

每一個人都熟知騎士所做的任何事情,這是因為詠游詩人用詩歌記載了騎士的事跡并將其進行傳唱。假設我們需要使用詠游詩人這個服務類來記載騎士的所有事跡。

詠游詩人是中世界的音樂記錄器

/**
 * Created by guo on 20/2/2018.
 * 詠游詩人,作為騎士的一個切面
 */
public class Minstrel {
    private PrintStream stream;

    public Minstrel(PrintStream stream) {
        this.stream = stream;
    }
    public void singBeforeQuest() {
        stream.println("Fa la la ,the Knight is so brabe");      //探險之前調用
    }
    public void singAfterQuest() {
        stream.println("Tee hee hhe,the brave knight " + "did embark on a quest");   //探險之后調用
    }
}

Minstrel只有兩個簡單的方法的類,在騎士執行每一個探險任務之前,singBeforeQuest()被調用;在騎士完成探險任務之后,singAfterQuest()方法被調用。在這兩種情況下,Minstrel都會通過一個PrintStream類來歌頌騎士的事跡,這個類通過構造器注入進來。

但利用AOP,你可以聲明詠游詩人西部歌頌騎士的 探險事跡,而騎士本身不直接訪問Minstrel的方法

要將Minstrel抽象為一個切面,你所需要做的事情就是在一個Spring配置文件中聲明它,,


                                    



    

            

                          

                            

    

這里使用了Spring的aop配置命名空間把Minstrel聲明為一個切面。

在這兩種方式中,pointcut-ref屬性都引用列名為為“embark”的切入點,該切入點實在前面的元素中定義的,并配置expression屬性來選擇所應用的通知。表達式的語法采用的是aspectJ的切點表達式語言。

Minstrel仍然是一個POJO,沒有任何代碼表明它要被作為一個切面使用,其次最重要的是Minstrel可以被應用到BraveKnight中,而BraveKnight不需要顯示的調用它,實際上,BraveKnight完全不知道MInstrel的存在

public class KnightAopMain {
   public static void main(String[] args) {
       ClassPathXmlApplicationContext context =
               new ClassPathXmlApplicationContext("spring/minstrel-AOP.xml");
      Knight knight = context.getBean(Knight.class);
      //Knight knight = (Knight) context.getBean("knight");
       knight.embarkOnQuest();
       context.close();
   }
}

輸出如下:
Fa la la ,the Knight is so brabe
Embarking on quest to slay the dragon!!,順便還可以學英語,一舉兩得。
Tee hee hhe,the brave knight did embark on a quest
1.1.4 小節

作者已經為我們展示了Spring通過面向POJO編程、DI、切面、模板技術來簡化Java開發中的復雜性。在這個工程中,展示了基于XML的配置文件中如何配置bean和切面,但這些文件是如何加載的呢?他們被加載到哪里呢?接下來讓我們了解下Spring容器,這是應用中的所有bean所駐留的地方。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68499.html

相關文章

  • Spring之旅第十二站:Spring Security 數據存儲、攔截請求 、認證用戶、*、

    摘要:啟用安全性這個簡單的默認配置指定了如何保護請求,以及客戶端認證用戶的方案。基于數據庫進行認證用戶數據通常會存儲在關系型數據庫中,并通過進行訪問。必須經過認證其他所有請求都是允許的,不需要認證。要求用戶不僅需要認證,還要具備權限。 Spring Security Spring Security 是基于Spring 應用程序提供的聲明式安全保護的安全框架。Spring Sercurity ...

    YuboonaZhang 評論0 收藏0
  • Spring之旅第十站:MVC配置、上傳文件、異常處理、跨重定向請求、為控制器添加通知

    摘要:依賴于對請求的支持。使用解析兼容的沒有構造器參數,也沒有要設置的參數,這樣,在應用上下文中,將其聲明為就會非常簡單。默認是沒有限制的整個請求的容量。 Spring MVC 高級的技術 本章內容: Spring MVC配置的替代方案 處理文件上傳 在控制器中處理異常 使用flash屬性 稍等還沒結束 說明 如果你有幸能看到。后面的章節暫時不更新了,改變學習方式了。重要理解思想,這本書...

    leanote 評論0 收藏0
  • Spring之旅第八站:Spring MVC Spittr舞臺的搭建、基本的控制器、請求的輸入、表

    摘要:請求旅程的第一站是的。的任務是將請求發送控制器控制器是一個用于處理請求的組件。處理映射器根據請求攜帶的信息來進行決策。這樣的結果就是,只能找到顯示聲明在配置類中的控制器。 構建Spring Web應用 說明 如果你有幸能看到。 1、本文參考了《Spring 實戰》重點內容,參考了GitHub上的代碼 2、本文只為記錄作為以后參考,要想真正領悟Spring的強大,請看原書。 3、在一次...

    maybe_009 評論0 收藏0
  • Spring之旅第七站:面向切面編程(AOP)

    摘要:面向切面的本章主要內容面向切面編程的基本原理通過創建切面使用注解為切面注入依賴。什么是面向切面編程切面能夠幫我們模塊化橫切關注點。在使用面向切面編程時,我們仍然在一個地方定義通知功能,而無需修改受影響的類。切面切面是通知和切點的結合。 面向切面的Spring 本章主要內容: 面向切面編程的基本原理 通過POJO創建切面 使用@Aspect注解 為AspectJ切面注入依賴。 說明 ...

    趙連江 評論0 收藏0
  • 第一章--Spring之旅

    摘要:兩種方式來表示的應用上下文。日志,事務管理和安全這樣的系統服務經常融入到具有核心業務邏輯的組件中去,這些系統服務通過被稱為橫切關注點。容器使用管理構成應用的組件,他會創建相互協作的組件之間的關聯。的生命周期四俯瞰的風景線模塊,,,, 完整代碼請見:https://github.com/codercuixi...為了降低Java開發的復雜性,Spring采用了以下4種策略: 基于poj...

    pkwenda 評論0 收藏0

發表評論

0條評論

thekingisalwaysluc

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<