自学内容网 自学内容网

编程中的智慧六:单例、原型、建造者

上一篇咱们结合Spring介绍了设计模式中的工厂模式相关方法,其实现在Java开发基本上都是基于Spring框架开发,所以后续我们在开发过程中基本上很少自己重写一个工厂模式,都是直接使用Spring来完成。今天咱们接着看剩下的创建型设计模式:单例、原型、建造者。

单例模式在Spring中的应用详解

单例模式确保一个类只有一个实例,并提供一个全局访问点。Spring框架默认情况下对所有Bean使用单例模式,即一个Bean只会被创建一次,并在整个Spring容器中共享。

1. 单例模式概述

单例模式包含以下角色:

  • 单例类:定义一个私有的构造函数,确保只能通过静态方法获取唯一实例。
  • 静态方法:提供获取单例实例的全局访问点。
2. 单例模式在Spring中的实现

源码分析:之前Spring源码相关内容已经分析过了这边直接贴代码来

Spring中的DefaultSingletonBeanRegistry类实现了单例模式。该类维护了一个缓存,用于存储单例Bean实例。

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    @Override
    public Object getSingleton(String beanName) {
        return this.singletonObjects.get(beanName);
    }

    protected void addSingleton(String beanName, Object singletonObject) {
        this.singletonObjects.put(beanName, singletonObject);
    }
}

在Spring容器初始化过程中,当一个Bean被创建时,如果其作用域为单例(默认情况),Spring会调用addSingleton方法将该Bean实例放入singletonObjects缓存中。在以后每次请求该Bean时,Spring会从缓存中直接返回该实例,而不再创建新的实例。

原型模式在Spring中的应用详解

原型模式通过克隆现有的对象来创建新对象。Spring支持原型作用域(prototype),每次请求一个原型作用域的Bean时,都会创建一个新的实例。

1. 原型模式概述

原型模式包含以下角色:

  • 原型接口:定义一个克隆方法。
  • 具体原型类:实现克隆方法,返回自身的一个副本。
2. 原型模式在Spring中的实现

源码分析:

在Spring中,通过配置Bean的作用域为prototype来实现原型模式。在DefaultListableBeanFactory中,处理原型作用域的代码如下:


// 如果是原型bean
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 实例化前置准备工作
beforePrototypeCreation(beanName);
// 开始实例化
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 实例化以后的处理工作
afterPrototypeCreation(beanName);
}
// 获取原型bean实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

 这里可以明显的看到如果是原型模式,Spring会直接调用createBean而不会从单例缓存池中获取。

构建者模式在Spring中的应用详解

构建者模式通过逐步构建复杂对象,允许创建者一步步构建其表示。Spring中的BeanDefinitionBuilder类使用了构建者模式,用于动态创建Bean定义。

1. 构建者模式概述

构建者模式包含以下角色:

  • 构建者:提供构建复杂对象的各个方法。
  • 具体构建者:实现构建者接口,构建具体的复杂对象。
  • 指导者:指导构建者如何构建复杂对象。
  • 产品:最终构建的复杂对象。
2. 构建者模式在Spring中的实现

源码分析:

Spring中的BeanDefinitionBuilder类使用了构建者模式:

public class BeanDefinitionBuilder {
    private AbstractBeanDefinition beanDefinition;

    private BeanDefinitionBuilder(Class<?> beanClass) {
        this.beanDefinition = new GenericBeanDefinition();
        this.beanDefinition.setBeanClass(beanClass);
    }

    public static BeanDefinitionBuilder genericBeanDefinition(Class<?> beanClass) {
        return new BeanDefinitionBuilder(beanClass);
    }

    public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
        this.beanDefinition.getPropertyValues().add(name, value);
        return this;
    }

    public AbstractBeanDefinition getBeanDefinition() {
        return this.beanDefinition;
    }
}

使用BeanDefinitionBuilder时,可以通过链式调用逐步设置Bean的各个属性,最终调用getBeanDefinition方法获取构建的Bean定义。例如:

BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyBean.class);
builder.addPropertyValue("name", "testName")
       .addPropertyValue("age", 30);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();

通过上述详细分析,我们可以看到Spring框架在其设计和实现中广泛应用了单例模式、原型模式和构建者模式。这些设计模式不仅提高了代码的可维护性和可扩展性,还使得Spring框架能够灵活地管理对象的创建和依赖注入。

当然实际生产中,我们业务处理的类基本上都是交给Spring管理的如Service、Controller、Mapper等,这些类默认情况下都是单例,当我指定作用域为Prototype的时候,其实就是走了不同的判断逻辑,然后每次都需要重新创建。


原文地址:https://blog.csdn.net/weixin_40735063/article/details/140593277

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!