DuckBlog

Duck Blog

唐如飞

( ^∀^)/欢迎\( ^∀^)

79 文章数
14 评论数

Spring配置多例Bean

tangrufei
2023-04-26 / 0 评论 / 189 阅读 / 0 点赞

前情提要

在之前的策略模式中提到了使用SpringBean来配合策略模式,但是再后来的工作中发现这中间有坑

List<BaseComponent> canvasData1= new ArrayList<>();
        for (CanvasData canvasDatum : canvasData) {
            BaseComponent component = (BaseComponent)SpringBeanUtils.getBean(canvasDatum.getComponent());
            BeanUtils.copyProperties(canvasDatum,component);
            BeanUtils.copyProperties(canvasDatum.getStyle(),component);
            canvasData1.add(component);
        }
        CanvasX canvasX = new CanvasX();
        BeanUtils.copyProperties(canvas,canvasX);
        canvasX.setCanvasData(canvasData1);

这一段我根据Component字段去匹配对应的Bean对象.然后添加到集合中,当时没有问题,但是后面发现如果这个集合中出现多个同类型Bean那么他们的字段属性却都一致了,我去打印他们的内存地址甚至都是一致的,这个时候我想到他们是以单利模式注册在Spring容器中的这是不符合我们需求的,我们需要修改为多例,当然,如果是支付等场景每个Bean不需要单独隔离的无需修改为多例

SpringBean的单例和多例使用

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

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

spring可以配置多例对象么

	答:可以。spring中bean可以被定义为两个模式:单例和多例
  • 单例:只有一个共享实例的存在,所有对这个bean的请求都会返回这个唯一的实例。不管new多少次。即所有请求都有一个对象来处理

  • 多例:对这个bean的每次请求都会创建一个新的bean实例,类似于new。

为什么用单例、多例

  • 之所以用单例,是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存;

  • 之所以用多例,是为了防止并发问题;即一个请求改变了对象的状态,此时对象又处理另一个请求,而之前请求对对象状态的改变导致了对象对另一个请求做了错误的处理;

什么时候用单例?什么时候用多例?

	答:当对象含有可改变状态时(在实际应用中该状态会改变),则多例,否则单例。例如dao和service层的数据一般不会有响应的属性改变,所以考虑单例,而controller层会存储很多需要操作的vo类,此时这个对象的状态就会被改变,则需要使用多例

如何配置多例?

	答:在bean上,加一个scope = “prototype”;如果不写个默认是true,也就是单例的,写了就是多例的

spring的bean为什么是单例的?

	答:为了提高性能。
	由于不会每次都新创建新对象,所以就减少了新生成实例的消耗。因为spring会通过反射或者cglib来生成bean实例这都是耗性能的操作,其次给对象分配内存也会涉及复杂算法。

	减少JVM垃圾回收,由于不会给每个请求都新生成bean实例,所以自然回收的对象少了。

	可以快速获取到bean,因为单例的获取bean操作除了第一次生成之外其余的都是从缓存里获取的所以很快。

Spring哪里用到了单例?

  • 1 Springboot 采用的是单例模式
  • 2 @Component注解默认实例化的对象是单例,如果 想声明成多例对象可以使用@Scope(“prototype”)
    @Component
    @Scope(“prototype”)
  • 3 @Repository默认单例
  • 4 @Service默认单例
  • 5 @Controller默认单例

bean的scope有五种

  • (1)singleton: 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例

  • (2)prototype:表示每次获得bean都会生成一个新的对象

  • (3)request:表示在一次http请求内有效(只适用于web应用)

  • (4)session:表示在一个用户会话内有效(只适用于web应用)

  • (5)globalSession:表示在全局会话内有效(只适用于web应用)

在多数情况,我们只会使用singleton和prototype两种scope,如果未指定scope属性,默认为singleton。

文章不错,扫码支持一下吧~
上一篇 下一篇
评论
来首音乐
光阴似箭
今日已经过去小时
这周已经过去
本月已经过去
今年已经过去个月