1. 程式人生 > >面試題:你簡歷中寫到熟悉Spring原始碼,那你給我說說它用到了那些設計模式?

面試題:你簡歷中寫到熟悉Spring原始碼,那你給我說說它用到了那些設計模式?

Spring作為業界的經典框架,無論是在架構設計方面,還是在程式碼編寫方面,都堪稱行內典範。好了,話不多說,開始今天的內容。

spring中常用的設計模式達到九種。

模板方法(Template Method)

spring的jdbc模板,對Spring原始碼的精妙真是佩服得五體投地,極為經典。

spring中真是集設計模式之大成,而且用得是爐火純青。模板方法(template method)就在spring中被大量使用,如:jdbcTemplate,hibernateTemplate,JndiTemplate以及一些包圍的包裝等都無疑使用了模板模式,但spring並不是單純使用了模板方法,而是在此基礎上做了創新,配合callback(回撥)一起使用,用得極其靈活。

所謂模板板式,就是在父類中定義演算法的主要流程,而把一些個性化的步驟延遲到子類中去實現,父類始終控制著整個流程的主動權,子類只是輔助父類實現某些可定製的步驟。

所謂回撥,就是方法引數中傳遞一個介面,父類在呼叫此方法時,必須呼叫方法中傳遞的介面的實現類。

以下是一個具體的例子,JdbcTemplate中的execute方法。

上面所述僅僅是Spring JdbcTemplte實現的基本原理,Spring JdbcTemplate內部還做了更多的事情,比如,把所有的基本操作都封裝到JdbcOperations介面內,以及採用JdbcAccessor來管理DataSource和轉換異常等。

策略(Strategy)

策略模式是對演算法的包裝,把使用演算法的責任和演算法本身分隔開,委派給不同的物件管理。策略模式通常把一系列的演算法包裝到一系列的策略類裡面,作為一個抽象策略類的子類。

spring中在例項化物件的時候用到Strategy模式,在SimpleInstantiationStrategy中有如下程式碼說明了策略模式的使用情況。

簡單工廠

又叫做靜態工廠方法(StaticFactory Method)模式,但不屬於23種GOF設計模式之一。

簡單工廠模式的實質是由一個工廠類根據傳入的引數,動態決定應該建立哪一個產品類。

spring中的BeanFactory就是簡單工廠模式的體現,根據傳入一個唯一的標識來獲得bean物件,但是否是在傳入引數後建立還是傳入引數前建立這個要根據具體情況來定。如下配置,就是在 HelloItxxz 類中建立一個 itxxzBean。

<beans>

工廠方法(Factory Method)

通常由應用程式直接使用new建立新的物件,為了將物件的建立和使用相分離,採用工廠模式,即應用程式將物件的建立及初始化職責交給工廠物件。

一般情況下,應用程式有自己的工廠物件來建立bean.如果將應用程式自己的工廠物件交給Spring管理,那麼Spring管理的就不是普通的bean,而是工廠Bean。

就以工廠方法中的靜態方法為例講解一下。

import java.util.Random;

建一個config.xm配置檔案,將其納入Spring容器來管理,需要通過factory-method指定靜態方法名稱。

<bean id="random"

測試:

public static void main(String[] args) {

單例模式(Singleton)

保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。

spring中的單例模式完成了後半句話,即提供了全域性的訪問點BeanFactory。但沒有從構造器級別去控制單例,這是因為spring管理的是是任意的java物件。

核心提示點:Spring下預設的bean均為singleton,可以通過singleton=“true|false” 或者 scope=“?”來指定。

介面卡(Adapter)

在Spring的Aop中,使用的Advice(通知)來增強被代理類的功能。

Spring實現這一AOP功能的原理就使用代理模式。

1、JDK動態代理。

2、CGLib位元組碼生成技術代理。

對類進行方法級別的切面增強,即,生成被代理類的代理類, 並在代理類的方法前,設定攔截器,通過執行攔截器重的內容增強了代理方法的功能,實現的面向切面程式設計。

public interface AdvisorAdapter {
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

代理(Proxy)

為其他物件提供一種代理以控制對這個物件的訪問。

從結構上來看和Decorator模式類似,但Proxy是控制,更像是一種對功能的限制,而Decorator是增加職責。

spring的Proxy模式在aop中有體現,比如JdkDynamicAopProxy和Cglib2AopProxy。

裝飾模式(Decorator)

也叫包裝器模式(Wrapper)。GOF在《設計模式》一書中給出的定義為:動態地給一個物件新增一些額外的職責。就增加功能來說,Decorator模式相比生成子類更為靈活。

在我們的專案中遇到這樣一個問題:我們的專案需要連線多個數據庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的資料庫。

這裡,你會首先想到得是在spring的applicationContext中配置所有的dataSource。這些dataSource可能是各種不同型別的,比如不同的資料庫:Oracle、SQL Server、MySQL等,也可能是不同的資料來源:比如apache 提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。然後sessionFactory根據客戶的每次請求,將dataSource屬性設定成不同的資料來源,以到達切換資料來源的目的。

Spring中用到的包裝器模式在類名上有兩種表現:一種是類名中含有Wrapper,另一種是類名中含有Decorator。基本上都是動態地給一個物件新增一些額外的職責。

 觀察者(Observer)

定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。

spring中Observer模式常用的地方是listener的實現。如ApplicationListener。


看到這裡還沒過癮,那麼就來群裡與更多的同學交流切磋技術,戳這裡:咱們來一起抱團取暖,好嗎?【Java高階網際網路架構:964357187】

相關推薦

試題簡歷熟悉Spring原始碼說說那些設計模式

Spring作為業界的經典框架,無論是在架構設計方面,還是在程式碼編寫方面,都堪稱行內典範。好了,話不多說,開始今天的內容。

面試官“看簡歷熟悉 Handler 機制聊聊 IdleHandler 吧?”

一. 序 Handler 機制算是 Android 基本功,面試常客。但現在面試,多數已經不會直接讓你講講 Handler 的機制,Looper 是如何迴圈的,MessageQueue 是如何管理 Message 等,而是基於場景去提問,看看你對 Handler 機制的掌握是否紮實。 本文就來聊聊 H

mysql試題字段@之前字符相同且大於等於2條的所有記錄

dex lec bst select wid from string sele 分享 公司發了一張面試題給我,題目如下: 在test數據庫中有個flow_user表,找出email字段中@之前字符相同且大於等於2條的所有記錄。最終效果如下: 答案: select

試題數組只出現一次的數字

new ++ array ear style 哈希表 else 兩個 個數 題目描述:一個整型數組裏除了兩個數字之外,其他的數字都出現了偶數次。請寫程序找出這兩個只出現一次的數字。 方法1:哈希表 //num1,num2分別為長度為1的數組。傳出參數 //將num1[0]

試題數組出現次數超過一半的數字

contain for get() [] more port put ray map 題目描述: 方法1:哈希表 import java.util.HashMap; public class Solution { public int MoreThanHalfNu

【圖文詳細 】HDFS試題介紹HadoopRPC協議以及底層什麼框架封裝的

用於將使用者請求中的引數或者應答轉換成位元組流以便跨機傳輸。 函式呼叫層:函式呼叫層主要功能是:定位要呼叫的函式,並執行該函式,Hadoop採用了java的反射機制和動態代理實現了函式的呼叫。 網路傳輸層:網路傳輸層描述了Client和Server之間訊息的傳輸方式,Hadoop採用了基

深入淺出經典試題從瀏覽器輸入URL到頁面載入發生什麼 - Part 2

備註: 因為文章太長,所以將它分為三部分,本文是第二部分。 第一部分:深入淺出經典面試題:從瀏覽器中輸入URL到頁面載入發生了什麼 - Part 1 TCP連線 DNS解析返回域名的IP之後,接下來就是瀏覽器要和該IP建立TCP連線了。為什麼是TCP而不是UDP?那是因為HTTP是基於TCP上的。

深入淺出經典試題從瀏覽器輸入URL到頁面載入發生什麼 - Part 3

深入淺出經典面試題:從瀏覽器中輸入URL到頁面載入發生了什麼 - Part 3 備註: 因為文章太長,所以將它分為三部分,本文是第三部分。 第一部分:深入淺出經典面試題:從瀏覽器中輸入URL到頁面載入發生了什麼 - Part 1 第二部分:深入淺出經典面試題:從瀏覽器中輸入URL到頁

資料結構經典試題在字串找到出現頻率大於50%的那個字元

來源:我是碼農,轉載請保留出處和連結! 本文連結:http://www.54manong.com/?id=13 問題描述: 在某個字串中(字串可能很長,比如有幾千萬個字元),請找出某個出現頻率大於50%的那個字元。例如:在字串"aabcdaa"中,字串長為7,字元'a'出現了4

劍指Offer試題9.二進位制1的個數

一、題目:二進位制中1的個數 題目:請實現一個函式,輸入一個整數,輸出該數二進位制表示中1的個數。例如把9表示成二進位制是1001,有2位是1。因此如果輸入9,該函式輸出2。 二、可能引起死迴圈的解法   一個基本的思路:先判斷整數二進位制表示中最右邊一位是不是1。接著把輸入的整數右移一位,此時

試題產生一個長度為100的陣列為陣列的每一項隨機填充1-100之間的數並且保證不重複

這是一道面試題: 參考網上3種方法,C#實現: 方法一: #region 方法一 //存放1-100個數 int[] num = new int[100]

試題不知道Head(頭節點)想要刪除連結串列的某一個節點

這是一道不是很新的面試題,最近在刷題時遇到了。網上有些說法我覺得不夠嚴謹,在這裡說一下自己的見解。 這裡不考慮雙向連結串列了,因為雙向連結串列是可以很輕鬆做到的。 答案都是比較統一的: 將所要刪除的節點的後一個節點的值copy到當前節點來。刪除後一個節點。

C語言試題查詢字串第一個不重複的字元

char findChar(char *s) { char *p,*q; p=q=s; while(*s != '\0') { while(*p++ != '\0')

不會看 Explain執行計劃簡歷熟悉 SQL優化

昨天中午在食堂,和部門的技術大牛們坐在一桌吃飯,作為一個卑微技術渣仔默默的吃著飯,聽大佬們高談闊論,研究各種高階技術,我TM也想說話可實在插不上嘴。 聊著聊著突然說到他上午面試了一個工作6年的程式設計師,表情挺複雜,他說:我看他簡歷寫著熟悉`SQL`語句調優,就問了下 `Explain` 執行計劃怎麼看?結

java基礎試題switch語句能否作用在byte上能否作用在long上能否作用在String上?

int 包裝類 println class ava col body package 面試題 package com.swift; public class Switch_Test { public static void main(String[] args

C#試題輸入一個長度100的數字字串判斷是否能被7整除

輸入一個長度為100的數字字串,首字元不能是0,判斷是否能被7整除。 思路:把字串中各個位數字拿出來與7取餘,如果最後為0,表示可以整除,不為0表示不能整除。 例如:504:5%=5,50%7=1,14%7=0等於0。那麼504能被7整除。             21

java多執行緒試題三個執行緒順序列印ABC重複10次

這個面試題,比較經典。有不同的解決思路。有的博文是用Join去實現。我面試的時候也是第一個想到的是用join叫A執行緒等待B執行緒執行完再執行。這樣的思路能實現,但是不好。雖然當時湊合著說服了面試官。先把程式碼貼出來 private Thread aThread,bThr

如果還不知道如何控制springbootbean的載入順序一定要看此篇

## 1.為什麼需要控制載入順序 `springboot`遵從約定大於配置的原則,極大程度的解決了配置繁瑣的問題。在此基礎上,又提供了spi機制,用`spring.factories`可以完成一個小元件的自動裝配功能。 在一般業務場景,可能你不大關心一個bean是如何被註冊進spring容器的。只需要把需

開發那些設計模式?在什麼場合?

所謂設計模式,就是一套被反覆使用的程式碼設計經驗的總結(情境中一個問題經過證實的一個解決方案)。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。設計模式使人們可以更加簡單方便的複用成功的設計和體系結構。將已證實的技術表述成設計模式也會使新系統開發者

曹工雜談為什麼很少需要改Spring原始碼因為擴充套件點太多說說Spring的後置處理器

前言 最近發了好幾篇,都是覆蓋框架原始碼,但是spring的程式碼,我是從沒覆蓋過,畢竟,如果方便擴充套件,沒誰想去改原始碼,而spring就是不需要改原始碼的那個,真的是“對擴充套件開放,對修改關閉”的典範。 就我說曾經用過的,spring的擴充套件點,就包括了listener、beanFactoryPos