【Spring源碼解析】—— 策略模式在Spring中的應用

1、         什麼是策略模式

策略模式的定義/含義:策略自己就是爲了實現某一個目標而採起的一種工做方式,所以只要可以達成目標,則採起哪種策略均可以;所以多種實際的策略之間是相互平行的。算法

注意:策略模式與模板模式是不一樣的,模板模式是定義了一個骨架(會有不少個步驟,其中可能包含必選和可選步驟,步驟之間可能會有必定的順序,模板模式在頂級骨架中可能會有部分實現,也可將部分實現延遲到子類中,例如:TestCase的過程,通常都包含setUp、testCase、tearDown操做,testCase須要子類自行實現,setUp和tearDown能夠直接經過super來進行調用;備註:模板模式後面會再專門整理,可能該部份內容會作更新),模板模式總體構成了一個完整的過程/算法,可對其中的某些步驟進行自行定製處理,而策略模式是調用者獨立於具體的策略算法,每一種具體策略自身就是完整的,策略A與策略B之間能夠自行替換,對調用者來講,不關注具體是經過策略A實現的仍是B實現的,經過引用傳入上下文,便可按照策略執行達到目標(策略能夠理解爲:異曲同工)ide

所以,在不少場景下均可以使用到策略模式,以你們熟悉的業務場景爲例:好比支付方式的選擇。函數

在Spring中,實例化對象的時候用到了Strategy模式,圖示以下所示:this

在上圖中:InstantiationStrategy爲抽象接口,SimpleInstantiationStrategy實現接口,可是在方法instantiate中進行判斷,針對bd中沒有MethodOverrides的,直接經過jdk反射進行構造函數調用,而針對有須要針對方法作MethodOverrides的,則能夠經過另外一種方式處理,在SimpleInstantiationStrategy中是經過:instantiateWithMethodInjection()方法處理的,在CglibSubclassingInstantiationStrategy中對該方法作了override實現。CglibSubclassingInstantiationStrategy繼承自SimpleInstantiationStrategy,對MethodInjection方法的實現以下:spa

@Override

protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,

      @Nullable Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass... return new CglibSubclassCreator(bd, owner).instantiate(ctor, args); }

 

經過static的class類CglibSubclassCreator進行instantiate操做,剩下的就是cglib內中的細節了,此處不分析。code

策略模式中包含的部分是:(1)抽象策略InstantiationStrategy接口對象

(2)具體策略SimpleInstantiationStrategy,被繼承後子類CglibSubclassingInstantiationStrategy,實現自抽象策略接口(3)上下文對策略的引用,在AbstractAutowireCapableBeanFactory中是經過new CglibSubclassingInstantiationStrategy賦值給InstantiationStrateg的引用,進而進行具體的方法調用,具體見下方代碼:blog

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory

      implements AutowireCapableBeanFactory {

   /** Strategy for creating bean instances. */
   private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();}

(注意:這裏通常是經過對抽象策略接口的引用,以後經過多實現的根據當時具體選擇的策略內容進行調用實現) 繼承

2、         自寫demo示例

根據上面提到的策略模式中須要的內容進行demo的編寫,分別是:抽象接口、具體實現、上下文引用及效果展現:接口

抽象接口定義:

package strategytest.demo;

public interface Strategy {
    PayInfo payForSometh();
}

其中PayInfo定義以下:

package strategytest.demo;

public class PayInfo {
    String payType;
    String payCode;
    String payDesc;

    public PayInfo(String payType, String payCode, String payDesc) {
        this.payType = payType;
        this.payCode = payCode;
        this.payDesc = payDesc;
    }

    public String getPayType() {
        return payType;
    }

    public String getPayDesc() {
        return payDesc;
    }

    public String getPayCode() {
        return payCode;
    }
}

具體策略接口實現:

package strategytest.demo;
public class ZhiFuBaoPay implements Strategy {
    @Override
    public PayInfo payForSometh() {
        System.out.println("調用支付寶支付功能,根據返回值進行PayInfo類信息的設置");
        PayInfo zhifubaoPayInfo= new PayInfo("支付寶", "0", "支付成功");
        return zhifubaoPayInfo;
    }
}

多個具體策略接口實現方式與上相似

上下文引用:

package strategytest.demo;
public class StrategyUse {
    public static void main(String[] args) {
        Strategy strategy = new WeiXinPay();
        PayInfo payinfo = strategy.payForSometh();
        System.out.println(payinfo.getPayType() + "," + payinfo.getPayCode() + "," + payinfo.getPayDesc());
    }
}

結果以下:

 

參考文章:Spring中的各類模式的介紹:https://www.jianshu.com/p/3ea48ecd7178  ——》這是策略模式的,而後也有其餘的模式,均可做爲參考

相關文章
相關標籤/搜索