spring源码设计模式分析(一)

简介: spring源码设计模式分析(一)

学源码应该去学里面的思想,学源码之前应该有一定的基础,才能够将源码看懂,也就是今天的所写的spring源码的设计模式。

在现实中,全局是核心,我们想要买车的话,需要创建一个车的工厂,然后需要一些原材料,然后生产出我们需要的对象,任何的工厂都是这么做的,而我们的程序源来于生活:

我们理解的spring从全局考虑 :其中有一个Spring的工厂:将原材料一直解析到对象。

先有set进去再get得到,比如数据库中有资源才可以获取资源,就是有舍才有得。

难题:道理简单,但是Spring工厂怎么把原材料组装成产品?

1.1、spring内部刨析,spring的设计模式,每一种设计模式都是解决问题而产生的

在spring中有13种设计模式:

创建型设计模式:主要作用是负责生产对象的,创建型设计模式这么多的原因,是因为它们是一套体系,来解决各种各样的问题产生的。

1.1.1、工厂模式

设计特点,在spring源码中是非常核心的地位,解决对象多态实例进行选择的问题。

代码如下:

  1. package com.spring.factory;

  2. /**
  3. * 支付接口:统一的规范
  4. */
  5. public interface Payment {
  6.    public  void pay();
  7. }

两种不同的支付,代码如下:

  1. package com.spring.factory;

  2. /**
  3. * 具体的场景微信支付
  4. * 抽象类没有具体的场景,只有类才有具体的场景
  5. * 从具体的场景里面看解决了什么问题
  6. */
  7. public class WxPayMent implements  Payment {
  8.    public void pay() {
  9.        System.out.println("微信支付");
  10.    }
  11. }
  12. package com.spring.factory;

  13. public class AliPayMent implements Payment {
  14.    private String Md5;
  15.    public void pay() {
  16.        System.out.println("支付宝支付");
  17.    }
  18. }

工厂 的代码如下:

  1. package com.spring.factory;

  2. public  class FactoryMode {
  3.    /**
  4.     * 获取支付宝实例
  5.     */
  6.    public  static  Payment getPayMent(String  payFlag) throws Exception {
  7.        if(payFlag=="Wx"){
  8.           return new WxPayMent();
  9.        }else if(payFlag=="Ali"){
  10.            return  new AliPayMent();
  11.        }else{
  12.            throw new Exception("支付信息不存在");
  13.        }
  14.    }
  15. }

测试的类的代码如下:

  1. package com.spring.factory;

  2. public  class DemoFactory {
  3.    public static void main(String[] args) throws Exception {
  4.        // 1、测试支付
  5.        Payment wx = FactoryMode.getPayMent("Wx");
  6.        wx.pay();
  7.    }
  8. }

测试的结果如下:

1.1.2、单例模式:

设计特点:解决对象单一的问题,简称之位为单例,在spring里面主要用来创建对象实例的。

代码如下:

在单例模式中:

在别的环境中创建单例,也就是spring中也是这样的,代码如下:

  1. package com.spring.singlaton;

  2. /**
  3. * 单例设计模式
  4. * 不管实例都少次,都永远是单例的
  5. */
  6. public class DemoSinglaton {
  7.    //单例模式只需要加载 一次,所以业务对象放到类里面就行了。
  8.    //在这个类写是代表典型的依赖的操作,避免了程序在这个DemoSinglaton类的当前环境不安全的问题,保证单例
  9.    //如果想要DemoService这个类在任何的环境下保持单例的话,需要在DemoService创建静态的构造方法
  10.     private   static  DemoService  demoService = new DemoService();
  11.     public  DemoService  getDemoService(){
  12.         //每次调用的时候都可以返回出来
  13.         return demoService;
  14.     }
  15. }

在自己的类的环境下创建单例:

饿汉模式:

模式特点:这种模式是线程不安全的,代码如下

  1. package com.spring.singlaton;

  2. /**
  3. * 具体的业务对象
  4. */
  5. public class DemoService {
  6.    /**
  7.     * 饿汉模式(在我需要之前帮我已经创建了)
  8.     */
  9.    private  static  DemoService demoService =new DemoService();
  10.    /**
  11.     * 私有的构造方法
  12.     */
  13.    private DemoService(){

  14.    }
  15.    public static DemoService  getDemoService(){
  16.        return demoService;
  17.    }

  18. }

解决线程安全,加一把锁,因为全局变量称之为线程的共享资源,对象实例是属于方法共享 的,代码如下:

懒汉模式,代码如下:

  1. package com.spring.singlaton;

  2. /**
  3. * 具体的业务对象
  4. */
  5. public class DemoService {
  6.    /**
  7.     * 饿汉模式(在我需要之前帮我已经创建了)
  8.     */
  9.    private  static  DemoService demoService=null;
  10.    /**
  11.     * 私有的构造方法
  12.     */
  13.    private DemoService(){

  14.    }
  15.    public static DemoService  getDemoService(){
  16.        if(demoService==null){
  17.            demoService=new DemoService();
  18.        }
  19.        return demoService;
  20.    }

  21. }

总结:如果对象非常大的话,可以用饿汉模式,为了减少在运行时耗费的性能。如果对象非常小的话,可以用懒汉式模式,懒加载。

1.1.3、原型模式

设计特点:解决对象多实例的问题,把当前对象的实例拷贝一份,代码如下:

在spring中默认是单例的,但是通过scope属性可以配置

clone:方法是直接从jvm虚拟机里创建的,是很快的。

  1. package com.spring.protype;

  2. /**
  3. * 原型设计模式:类需要实现Cloneable接口,因为在jvm中拷贝需要实现Cloneable接口
  4. *Cloneable:就是一个规范而已,里面什么都没有
  5. */
  6. public class ProtypeMode implements  Cloneable {
  7.    //private ProtypeMode protypeMode =new ProtypeMode();
  8.    public ProtypeMode  getProtypeMode() throws CloneNotSupportedException {
  9.        return (ProtypeMode) super.clone();
  10.    }
  11. }

1、原型的设计模式中涉及到深拷贝,和浅拷贝的问题,本质是在基本类型和引用数据类型,如果是浅拷贝的话,拷贝的是对象的引用,指向的还是同一个对象,深拷贝,拷贝的是对象的实例和对象都给拷贝了,重新在生成一个对象出来,基本的数据类型没有深浅之分,原型设计模式在优化的时候非常重要。

2、使用场景:原型设计模式可以提高性能,因为new的时候非常耗时,复杂,优化的本质将流程简单化,节约时间。1、避免了new创建对象的过程new对象的过程会在jvm中会创建对象的头,对象的数据等等。2、一种对象在创建的过程中,非常耗时和耗资源的时候,而且考虑多个实例使用的情况。3、数据库连接池,数据库的连接池不用每一次都new对象 ,Map是存储本质,map存储的性能高,也可以将单例模式和原型设计模式组合起来用,是最好的。

1.1.12、建造者设计模式

设计特点:解决对象在构建过程中动态设置属性(依赖)的问题,在mybatis中的mapperStatement中就是用的建造者设计模式来实现的,里面对象基本都是由建造者设计模式来创建的,里面的属性都可以动态配置的,依赖不是必须的情况下使用,统一的规范。

代码如下:

  1. package com.spring.builder;

  2. /**
  3. * 建造者模式
  4. * @author qiu
  5. *
  6. */
  7. public class BuildMode {

  8.    private String name;
  9.    private String password;
  10.    private String password1;
  11.    private String password2;
  12.    private String password3;
  13.    private String password4;
  14.    private String password5;
  15.    private String password6;
  16.    private String password7;
  17.    private String password8;
  18.    private String password9;
  19.    private String password10;
  20.    private String password11;
  21.    private String password12;



  22.    public String getName() {
  23.        return name;
  24.    }

  25.    public void setName(String name) {
  26.        this.name = name;
  27.    }

  28.    public String getPassword() {
  29.        return password;
  30.    }

  31.    public void setPassword(String password) {
  32.        this.password = password;
  33.    }

  34.    public String getPassword1() {
  35.        return password1;
  36.    }

  37.    public void setPassword1(String password1) {
  38.        this.password1 = password1;
  39.    }

  40.    public String getPassword2() {
  41.        return password2;
  42.    }

  43.    public void setPassword2(String password2) {
  44.        this.password2 = password2;
  45.    }

  46.    public String getPassword3() {
  47.        return password3;
  48.    }

  49.    public void setPassword3(String password3) {
  50.        this.password3 = password3;
  51.    }

  52.    public String getPassword4() {
  53.        return password4;
  54.    }

  55.    public void setPassword4(String password4) {
  56.        this.password4 = password4;
  57.    }

  58.    public String getPassword5() {
  59.        return password5;
  60.    }

  61.    public void setPassword5(String password5) {
  62.        this.password5 = password5;
  63.    }

  64.    public String getPassword6() {
  65.        return password6;
  66.    }

  67.    public void setPassword6(String password6) {
  68.        this.password6 = password6;
  69.    }

  70.    public String getPassword7() {
  71.        return password7;
  72.    }

  73.    public void setPassword7(String password7) {
  74.        this.password7 = password7;
  75.    }

  76.    public String getPassword8() {
  77.        return password8;
  78.    }

  79.    public void setPassword8(String password8) {
  80.        this.password8 = password8;
  81.    }

  82.    public String getPassword9() {
  83.        return password9;
  84.    }

  85.    public void setPassword9(String password9) {
  86.        this.password9 = password9;
  87.    }

  88.    public String getPassword10() {
  89.        return password10;
  90.    }

  91.    public void setPassword10(String password10) {
  92.        this.password10 = password10;
  93.    }

  94.    public String getPassword11() {
  95.        return password11;
  96.    }

  97.    public void setPassword11(String password11) {
  98.        this.password11 = password11;
  99.    }

  100.    public String getPassword12() {
  101.        return password12;
  102.    }

  103.    public void setPassword12(String password12) {
  104.        this.password12 = password12;
  105.    }


  106.    // 先创建一个实例存在
  107.    private static BuildMode bulidMode = new BuildMode();

  108.    // 才能进行调用
  109.    public static BuildMode buildName(String name){
  110.        bulidMode.setName(name);

  111.        return bulidMode;
  112.    }

  113.    // 才能进行调用
  114.    public static BuildMode buildPassword(String password){
  115.        bulidMode.setPassword(password);

  116.        return bulidMode;
  117.    }
  118.    // 才能进行调用
  119.    public static BuildMode buildPassword1(String password1){
  120.        bulidMode.setPassword2(password1);

  121.        return bulidMode;
  122.    }
  123.    // 才能进行调用
  124.    public static BuildMode buildPassword2(String password2){
  125.        bulidMode.setPassword3(password2);

  126.        return bulidMode;
  127.    }
  128.    // 才能进行调用
  129.    public static BuildMode buildPassword3(String password3){
  130.        bulidMode.setPassword4(password3);

  131.        return bulidMode;
  132.    }
  133.    // 才能进行调用
  134.    public static BuildMode buildPassword4(String password4){
  135.        bulidMode.setPassword5(password4);

  136.        return bulidMode;
  137.    }




  138. }
  139. package com.spring.builder;

  140. public class BuildTest {
  141.    public static void main(String[] args) {
  142.        BuildMode bulidMode = BuildMode
  143.                .buildName("Tony")
  144.                .buildPassword("fadd")
  145.                .buildPassword1("dd")
  146.                .buildPassword2("saassa");
  147.    }
  148. }

应用场景:在配置对象的时候用的非常多,链式操作,返回的对象 才可以称之为链式,代替set方法来统一维护的。

相关文章
|
22天前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
49 14
|
2月前
|
Java 调度 开发者
spring的@Scheduled()有几种定时模式?
【10月更文挑战第12天】spring的@Scheduled()有几种定时模式?
121 1
|
2月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
626 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
|
2月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
229 2
|
3月前
|
设计模式 Java Spring
spring源码设计模式分析(五)-策略模式
spring源码设计模式分析(五)-策略模式
|
3月前
|
负载均衡 Java 网络架构
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
168 5
|
3月前
|
消息中间件 设计模式 缓存
spring源码设计模式分析(四)-观察者模式
spring源码设计模式分析(四)-观察者模式
|
3月前
|
XML 存储 Java
Spring-源码深入分析(二)
Spring-源码深入分析(二)
|
3月前
|
XML 设计模式 Java
Spring-源码深入分析(一)
Spring-源码深入分析(一)
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
236 2