学源码应该去学里面的思想,学源码之前应该有一定的基础,才能够将源码看懂,也就是今天的所写的spring源码的设计模式。
在现实中,全局是核心,我们想要买车的话,需要创建一个车的工厂,然后需要一些原材料,然后生产出我们需要的对象,任何的工厂都是这么做的,而我们的程序源来于生活:
我们理解的spring从全局考虑 :其中有一个Spring的工厂:将原材料一直解析到对象。
先有set进去再get得到,比如数据库中有资源才可以获取资源,就是有舍才有得。
难题:道理简单,但是Spring工厂怎么把原材料组装成产品?
1.1、spring内部刨析,spring的设计模式,每一种设计模式都是解决问题而产生的
在spring中有13种设计模式:
创建型设计模式:主要作用是负责生产对象的,创建型设计模式这么多的原因,是因为它们是一套体系,来解决各种各样的问题产生的。
1.1.1、工厂模式
设计特点,在spring源码中是非常核心的地位,解决对象多态实例进行选择的问题。
代码如下:
package com.spring.factory;
/**
* 支付接口:统一的规范
*/
public interface Payment {
public void pay();
}
两种不同的支付,代码如下:
package com.spring.factory;
/**
* 具体的场景微信支付
* 抽象类没有具体的场景,只有类才有具体的场景
* 从具体的场景里面看解决了什么问题
*/
public class WxPayMent implements Payment {
public void pay() {
System.out.println("微信支付");
}
}
package com.spring.factory;
public class AliPayMent implements Payment {
private String Md5;
public void pay() {
System.out.println("支付宝支付");
}
}
工厂 的代码如下:
package com.spring.factory;
public class FactoryMode {
/**
* 获取支付宝实例
*/
public static Payment getPayMent(String payFlag) throws Exception {
if(payFlag=="Wx"){
return new WxPayMent();
}else if(payFlag=="Ali"){
return new AliPayMent();
}else{
throw new Exception("支付信息不存在");
}
}
}
测试的类的代码如下:
package com.spring.factory;
public class DemoFactory {
public static void main(String[] args) throws Exception {
// 1、测试支付
Payment wx = FactoryMode.getPayMent("Wx");
wx.pay();
}
}
测试的结果如下:
1.1.2、单例模式:
设计特点:解决对象单一的问题,简称之位为单例,在spring里面主要用来创建对象实例的。
代码如下:
在单例模式中:
在别的环境中创建单例,也就是spring中也是这样的,代码如下:
package com.spring.singlaton;
/**
* 单例设计模式
* 不管实例都少次,都永远是单例的
*/
public class DemoSinglaton {
//单例模式只需要加载 一次,所以业务对象放到类里面就行了。
//在这个类写是代表典型的依赖的操作,避免了程序在这个DemoSinglaton类的当前环境不安全的问题,保证单例
//如果想要DemoService这个类在任何的环境下保持单例的话,需要在DemoService创建静态的构造方法
private static DemoService demoService = new DemoService();
public DemoService getDemoService(){
//每次调用的时候都可以返回出来
return demoService;
}
}
在自己的类的环境下创建单例:
饿汉模式:
模式特点:这种模式是线程不安全的,代码如下
package com.spring.singlaton;
/**
* 具体的业务对象
*/
public class DemoService {
/**
* 饿汉模式(在我需要之前帮我已经创建了)
*/
private static DemoService demoService =new DemoService();
/**
* 私有的构造方法
*/
private DemoService(){
}
public static DemoService getDemoService(){
return demoService;
}
}
解决线程安全,加一把锁,因为全局变量称之为线程的共享资源,对象实例是属于方法共享 的,代码如下:
懒汉模式,代码如下:
package com.spring.singlaton;
/**
* 具体的业务对象
*/
public class DemoService {
/**
* 饿汉模式(在我需要之前帮我已经创建了)
*/
private static DemoService demoService=null;
/**
* 私有的构造方法
*/
private DemoService(){
}
public static DemoService getDemoService(){
if(demoService==null){
demoService=new DemoService();
}
return demoService;
}
}
总结:如果对象非常大的话,可以用饿汉模式,为了减少在运行时耗费的性能。如果对象非常小的话,可以用懒汉式模式,懒加载。
1.1.3、原型模式
设计特点:解决对象多实例的问题,把当前对象的实例拷贝一份,代码如下:
在spring中默认是单例的,但是通过scope属性可以配置
clone:方法是直接从jvm虚拟机里创建的,是很快的。
package com.spring.protype;
/**
* 原型设计模式:类需要实现Cloneable接口,因为在jvm中拷贝需要实现Cloneable接口
*Cloneable:就是一个规范而已,里面什么都没有
*/
public class ProtypeMode implements Cloneable {
//private ProtypeMode protypeMode =new ProtypeMode();
public ProtypeMode getProtypeMode() throws CloneNotSupportedException {
return (ProtypeMode) super.clone();
}
}
1、原型的设计模式中涉及到深拷贝,和浅拷贝的问题,本质是在基本类型和引用数据类型,如果是浅拷贝的话,拷贝的是对象的引用,指向的还是同一个对象,深拷贝,拷贝的是对象的实例和对象都给拷贝了,重新在生成一个对象出来,基本的数据类型没有深浅之分,原型设计模式在优化的时候非常重要。
2、使用场景:原型设计模式可以提高性能,因为new的时候非常耗时,复杂,优化的本质将流程简单化,节约时间。1、避免了new创建对象的过程,new对象的过程会在jvm中会创建对象的头,对象的数据等等。2、一种对象在创建的过程中,非常耗时和耗资源的时候,而且考虑多个实例使用的情况。3、数据库连接池,数据库的连接池不用每一次都new对象 ,Map是存储本质,map存储的性能高,也可以将单例模式和原型设计模式组合起来用,是最好的。
1.1.12、建造者设计模式
设计特点:解决对象在构建过程中动态设置属性(依赖)的问题,在mybatis中的mapperStatement中就是用的建造者设计模式来实现的,里面对象基本都是由建造者设计模式来创建的,里面的属性都可以动态配置的,依赖不是必须的情况下使用,统一的规范。
代码如下:
package com.spring.builder;
/**
* 建造者模式
* @author qiu
*
*/
public class BuildMode {
private String name;
private String password;
private String password1;
private String password2;
private String password3;
private String password4;
private String password5;
private String password6;
private String password7;
private String password8;
private String password9;
private String password10;
private String password11;
private String password12;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword1() {
return password1;
}
public void setPassword1(String password1) {
this.password1 = password1;
}
public String getPassword2() {
return password2;
}
public void setPassword2(String password2) {
this.password2 = password2;
}
public String getPassword3() {
return password3;
}
public void setPassword3(String password3) {
this.password3 = password3;
}
public String getPassword4() {
return password4;
}
public void setPassword4(String password4) {
this.password4 = password4;
}
public String getPassword5() {
return password5;
}
public void setPassword5(String password5) {
this.password5 = password5;
}
public String getPassword6() {
return password6;
}
public void setPassword6(String password6) {
this.password6 = password6;
}
public String getPassword7() {
return password7;
}
public void setPassword7(String password7) {
this.password7 = password7;
}
public String getPassword8() {
return password8;
}
public void setPassword8(String password8) {
this.password8 = password8;
}
public String getPassword9() {
return password9;
}
public void setPassword9(String password9) {
this.password9 = password9;
}
public String getPassword10() {
return password10;
}
public void setPassword10(String password10) {
this.password10 = password10;
}
public String getPassword11() {
return password11;
}
public void setPassword11(String password11) {
this.password11 = password11;
}
public String getPassword12() {
return password12;
}
public void setPassword12(String password12) {
this.password12 = password12;
}
// 先创建一个实例存在
private static BuildMode bulidMode = new BuildMode();
// 才能进行调用
public static BuildMode buildName(String name){
bulidMode.setName(name);
return bulidMode;
}
// 才能进行调用
public static BuildMode buildPassword(String password){
bulidMode.setPassword(password);
return bulidMode;
}
// 才能进行调用
public static BuildMode buildPassword1(String password1){
bulidMode.setPassword2(password1);
return bulidMode;
}
// 才能进行调用
public static BuildMode buildPassword2(String password2){
bulidMode.setPassword3(password2);
return bulidMode;
}
// 才能进行调用
public static BuildMode buildPassword3(String password3){
bulidMode.setPassword4(password3);
return bulidMode;
}
// 才能进行调用
public static BuildMode buildPassword4(String password4){
bulidMode.setPassword5(password4);
return bulidMode;
}
}
package com.spring.builder;
public class BuildTest {
public static void main(String[] args) {
BuildMode bulidMode = BuildMode
.buildName("Tony")
.buildPassword("fadd")
.buildPassword1("dd")
.buildPassword2("saassa");
}
}
应用场景:在配置对象的时候用的非常多,链式操作,返回的对象 才可以称之为链式,代替set方法来统一维护的。