【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  ——》这是策略模式的,而后也有其余的模式,均可做为参考

相关文章
相关标签/搜索