为啥Spring把bean设计成单态的,这样的设计的好处是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥Spring把bean设计成单态的,这样的设计的好处是啥?相关的知识,希望对你有一定的参考价值。

设计的时候没有考虑到并发访问,安全问题吗?

spring设计成单态,一方面是为了效率,还有一方面是节省内存开销.
事务,一般用spring都会为这些单态类的某些方法加上事务.声明式事务.
参考技术A 是单例模式吧?
Spring Bean作用域:scope属性
作用域 描述
singleton 默认值,在每个Spring IoC容器中一个bean定义对应一个对象实例。
prototype 一个bean定义对应多个对象实例。
request 在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring applicationContext情形下有效。
session 在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
global session 在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。追问

我知道这些bean的作用域,为什么Spring设计的时候不直接把bean设计成多态的,这样就是线程安全的,每一次HTTP请求都生成新的bean,在修改,展现数据的时候也就不会出现乱套了,而Spring把bean设计成单态肯定有它的好处,要不然Spring就是挖个坑让自己跳,它的好处什么吗?设计成单态的原理是什么?

参考技术B 设计成什么态主要和你的需求有关系,各有优劣!

访问具有单态的变体

【中文标题】访问具有单态的变体【英文标题】:Visit a variant with a monostate 【发布时间】:2018-09-27 06:47:28 【问题描述】:

我无法理解变体。

我读到,我可以使用 std::monostate 来暗示空状态作为变体内部的替代方案之一。但是,我该如何使用由 std::visit 提供的访问者模式?

#include <variant>


struct Visitor
  void operator()(double);
  void operator()(int);
;

int main() 
  std::variant<std::monostate, int, double> v = 1;

  std::visit(Visitor, v);

不起作用,也没有为 std::monostate 提供调用运算符重载。

如果我尝试为调用运算符包含一个通用引用重载,它只会匹配所有内容并且不再使用两个特定重载

【问题讨论】:

无法复制:godbolt.org/z/GAPn3v 【参考方案1】:

我添加了适当的访问者方法,它适用于https://wandbox.org/ c++2a

你有什么问题?

#include <iostream>
#include <variant>


struct Visitor
  void operator()(double) std::cout << "Double!" << std::endl; ;
  void operator()(int) std::cout << "Int!" << std::endl; ;

  // that was missing:
  void operator()(std::monostate) std::cout << "Mono!" << std::endl; ;
;

int main() 
  std::variant<std::monostate, int, double> v = 1;
  std::variant<std::monostate, int, double> w;

  std::visit(Visitor, v);
  std::visit(Visitor, w);

【讨论】:

【参考方案2】:

不起作用,也没有为 std::monostate 提供调用运算符重载。

std::monostate 上的额外重载确实对我有用:

struct Visitor 
   void operator()(double)
   void operator()(int)
   void operator()(std::monostate)
;

这样使用时

std::variant<std::monostate, int, double> v = 1;
std::visit(Visitor, v); // invokes the int overload

v= 1.234;
std::visit(Visitor, v); // ... and the double overload

v = std::monostate;
std::visit(Visitor, v); // ... and finally the std::monostate overload

它应该很高兴地编译并产生预期的行为。

【讨论】:

确实如此,奇怪,也许我昨天晚上太累了。非常感谢你们。

以上是关于为啥Spring把bean设计成单态的,这样的设计的好处是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Spring 实现两种设计模式:工厂模式和单态模式

访问具有单态的变体

C/C++为啥日志模块要设计成单例模式的?有啥好处?

Spring如何实现IOC容器功能

单例模式详解——步步改进

单态(单例)设计模式