Spring中Bean的单例和多例使用说明

 更新时间:2022年06月13日 11:09:29   作者:inner_peace8  
这篇文章主要介绍了Spring中Bean的单例和多例使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Bean的单例和多例使用

在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例)

  • singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例。
  • prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new。

Spring bean 默认是单例模式。

实战演示

在配置文件中,修改这句代码为:

在测试类中,修改代码为:

<bean id="hi" class="com.test.Hi" init-method="init" scope="singleton">
ApplicationContext context = new FileSystemXmlApplicationContext("applicationContext.xml");
Hi hi1 = (Hi) context.getBean("hi");
Hi hi2 = (Hi) context.getBean("hi");
System.out.println(hi1);
System.out.println(hi2);

结果为:

结论:二个变量指向一个对象。

将配置文件改为:

<bean id="hi" class="com.test.Hi" init-method="init" scope="prototype">

其他的不变,运行测试类,结果为:

结论:每次访问bean,均创建一个新实例。

此外,在springBoot项目中如果要配置单例或者多例,可以在对应的bean上加一个@scope()注解

Spring单例bean与原型bean区别和创建过程

Spring官方文档中给出的bean的scope有五种

  • singleton
  • prototype
  • request
  • session
  • global session

实际上,Spring最基本的scope只有两种,即singleton和prototype。

可以参看spring源码中的BeanDefinition.java的定义,只有这两种:

String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

其他的各种scope都是自行扩展出来的。包括官网文档中没有列出来的 servletContenxt 、thread;SpringCloud提供的refresh等。

其继承关系大致如下

singletonScope与prototypeScope

singletonScope,即单例Bean,顾名思义具有单例模式的所有特性,在spring容器里面只会初始化出一个bean实例,存于缓存中。后续的请求都公用这个对象。

最简单的创建单例bean的方式,就是直接在类名上面加@Service注解。

prototypeScope,即原型Bean,每次请求时都会创建新的bean实例直接使用。

创建原型Bean,需要显示指定scope属性。

可以参看spring的 AbstractBeanFactory.java 中的 doGetBean 方法,理解两种bean的使用过程

单例bean的创建

单例bean被存放在这样一个Map中:

/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

上面代码中的 getSingleton 方法,作用就是先根据beanName从map(singletonObjects)中取bean,

取不到的话,调用后面的singletonFactory的createBean方法创建单例bean(这里的createBean是抽象方法,具体实现交给了各种scope的实现类负责),

创建成功以后,存入singletonObjects,并将引用返回。

原型bean的创建

中规中矩,上来就直接创建,然后分befoew、createBean、after三个生命周期,对于具体实现提供充分的支持。

至于最后一句 getObjectForBeanInstance,如果上面创建的是一个普通bean则直接返回;如果创建的是一个BeanFactory的实例,则利用工厂实例创建新的bean,然后返回。

对于其他扩展出来的scope

会利用 接口 Scope.java 中定义的这个方法,调用各扩展scope的实现去创建bean:

// Return the object with the given name from the underlying scope,
Object get(String name, ObjectFactory<?> objectFactory);

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot数据库查询超时配置详解

    SpringBoot数据库查询超时配置详解

    这篇文章主要介绍了SpringBoot数据库查询超时配置,超时配置可以避免长时间占用数据库连接,提高系统的响应速度和吞吐量,还可以快速的反馈可以提升用户体验,避免用户因长时间等待而感到挫败,文中有详细的代码示例供大家参考,需要的朋友可以参考下
    2024-11-11
  • 详谈Java8新特性泛型的类型推导

    详谈Java8新特性泛型的类型推导

    这篇文章我们来看一篇关于Java8新特性之泛型的类型推导,希望这篇文章能够让各位深入到了解到关于Java8新特性之泛型的类型用法,有需要的朋友们下面来一起看看吧。
    2016-09-09
  • Java使用Jdbc连接Oracle执行简单查询操作示例

    Java使用Jdbc连接Oracle执行简单查询操作示例

    这篇文章主要介绍了Java使用Jdbc连接Oracle执行简单查询操作,结合实例形式详细分析了java基于jdbc实现Oracle数据库的连接与查询相关操作技巧,需要的朋友可以参考下
    2019-09-09
  • Java List的sort()方法改写compare()实现升序,降序,倒序的案例

    Java List的sort()方法改写compare()实现升序,降序,倒序的案例

    这篇文章主要介绍了Java List的sort()方法改写compare()实现升序,降序,倒序的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • SpringBoot如何获取src/main/resource路径下的文件

    SpringBoot如何获取src/main/resource路径下的文件

    这篇文章主要介绍了SpringBoot如何获取src/main/resource路径下的文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringBoot 动态配置Profile环境的方式

    SpringBoot 动态配置Profile环境的方式

    这篇文章主要介绍了SpringBoot 动态配置Profile环境的方式,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • MybatisPlus代码生成器含XML文件详解

    MybatisPlus代码生成器含XML文件详解

    这篇文章主要介绍了MybatisPlus代码生成器含XML文件详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Spring Boot 中启用定时任务的操作方法

    Spring Boot 中启用定时任务的操作方法

    文章主要介绍了如何在Spring Boot中启用定时任务,包括使用@EnableScheduling注解、配置项控制定时任务是否开启以及如何关闭cron定时任务,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • 浅谈在Spring中如何使用数据源(DBCP、C3P0、JNDI)

    浅谈在Spring中如何使用数据源(DBCP、C3P0、JNDI)

    这篇文章主要介绍了浅谈在Spring中如何使用数据源(DBCP、C3P0、JNDI),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • Java如何解析html中的内容并存到数据库详解

    Java如何解析html中的内容并存到数据库详解

    最近用到了Java解析Html的一个库Jsoup,所以下面这篇文章主要给大家介绍了关于Java如何解析html中的内容并存到数据库的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03

最新评论