Arch. Components 2(三)|学习笔记

简介: 快速学习 Arch. Components 2(三)

开发者学堂课程【高校精品课-上海交通大学-企业级应用体系架构:Arch. Components 2】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/75/detail/15820


Arch. Components 2(三)

 

内容介绍:

一、有状态、无状态服务

二、scope 的取值


image.png

这时刚才例子的结构,主要代码如下:

UserController.java

@RestController

public class UserController {

@Autowired

private UserService userService;

@GetMapping(value = "/findUser/{id}")

public User findOne(@PathVariable("id") String id) {

System.out.println(userService);

return userService.findUserByld(Integer.valueOf(id));

};

}

UserServicelmpl.java

@Service

public class UserServicelmpl implements UserService {

@Autowired

private UserDao userDao;

@Override

public User findUserByld(Integer id) {

return userDao.findOne(id);

}

}

controler 会发送请求,service 实现类会调用 dao 进行访问。在两个浏览器里面,各自模拟一个客户端发送请求,上述代码没有做 scope 的注解,所以默认是 singleton 的,在下面可以看到,运行 n 多次下来,service instance 只有一个。

image.png

如果将下面的 UserServicelmpl.java 变成 prototype,上面保持 singleton 不变。在两个浏览器运行,会发现在当前配置里,虽然变成 prototype,理论来说,controler 是一个,但是每次访问 UserServicelmpl 时都应该应该创建一个新的对象,但运行后发现仍然只有一个 service instance,为什么呢?

usercontroler 是 singleton 的,因为没有做注解。会靠 spring 注入 userservice,创建 usercontroler 之后,就会创建 UserServicelmpl.java 的对象注入service里,所以每次接收请求的时候,都在调用注入对象的例子,相应方法是finduserbyid。所以尽管是 prototype,只有一个 service instance。这是注入机制导致的。

改变方法,将第一个 controler 也改成 prototype,运行时会发现每次都不一样,也就是每一个会生成一个新的controler 对象,尽管是注入进去的,但 Usercontroler 是多个,所以 UserService 也是多个。

image.png

如果 controler 保持不变,默认 scope 是 singleton。下面是通过 applicationcontext 的方式来获取 service 对象,而不是直接要求注入 userservice。运行结果就是四个对象都不相同。这个方案会更好一些,实际上是在保证controler 只有一个的同时会有四个,而不是像前边,controler 有四个,下面的也有四个。

image.png

把下面换成 session,就会发现2个浏览器里会有2个对象,但在同一个浏览器中发出的请求,会在同一个对象上调用,session 在浏览器里发出多个请求,始终用同一个对象,但是在不同的 session 里,会创建新的对象。

image.png

无法回避有状态的服务,还是会用到 prototype 或 session,不能只用默认的 singleton。在两个浏览器里不能只使用singleton,因为确实有可能需要为不同的用户维护他们各自的状态。一旦用 prototype 或 session,在内存当中,对象不止一个,只要不止一个,对服务器来说都是一种压力,压力随着客户端数量的增大而增多,所以要考虑好系统应该是什么样子的。

在 controler 和 service 两个类里,设有 prototype 和 session,可以看到实例的差异,那到底应该怎么设计呢?

image.png

系统是分层的,有 controler 层,有 DAO 层,DAO 的实现层,实体层,访问实层,service 层等等。在系统里,不能完全回避状态,总是有一些状态是需要维护的。

状态应该集中在某一层,显然,service 层是一个比较好的地方,controler 层是整个应用的入口,大量的请求过来之后,会通过 controler 做分发,会调用 service 进行操作,在入口的地方创建很多对象显然是不合适的,这和 controler层默认是 singleton 是一个道理。

DAO 层是访问下面的数据库,道理来说,不应该和具体的用户相关,多个 DAO 是没有意义的,而且多个 DAO 还会带来问题,在访问底层的数据库时候,多个 DAO 访问就像数据库原理中的事务,多个事务并发执行,是一个难解决的问题,所以 DAO 层不合适。只剩下 service 层是合适的。

所以一个系统在运行的时候,一些是有状态的,一些是无状态的。有状态的应尽量的少,将他放在服务器这层。如果想做得更好,可以把服务层拆得细一些,拆分成两个层,一层无状态服务层,一层有状态服务层。一层的scope是singleton,一层是 prototype 或者 section。在服务层有它的实践逻辑,大多数逻辑中,可能都不需要定义变量,当应用比较复杂之后,把不需要定义自己变量的东西包装在一层,叫做无状态服务层;把需要包装状态的那些服务放在有状态服务层,在无状态服务层之下。

也就是说,上层的无状态层没有任何的属性,只有方法,会调用下面的有状态服务层,有状态服务层包含一些成员方法为不同的用户维护各自的状态。这样才是一种比较理想的方案。可以把有状态的东西限制的尽可能小,整体数量应该进尽可能少。

原因就是有状态的东西会大量消耗内存,如果想节约内存,性能又会大幅下降。原因是在硬盘和内存之间做频繁的换进换出。

本质上就是要节约使用内存,内存的状态和持久化的状态做优化的管理和存储。在这种情况下,把内存使用率提高,尽量让有状态东西少。但有状态的东西是不可能没有的,如果没有就会变成整个服务器端全部是无状态的,可以把状态全部推到客户端处理,但客户端至少要有2个存储用户的会话状态,cookie 和 localstroge 是可以用来存放的。但是把状态存在客户端是需要格外的仔细的。毕竟这两个东西是很容易打开之后篡改的,所以是有隐患的。

好处是服务器端可以不用管状态,服务器端全部都是 singleton对象,状态全部通过 cookie 和 localstroge 写回到客户端。这样需要在 cookie 和 l ocalstroge 的保护上面下功夫。

总的来说,我们要谈的就是用户的会话状态如何保存,有状态、无状态的服务是什么意思,按照给出的例子自己运行可能会有比较深刻的体会。

相关文章
|
5月前
|
数据采集 存储 Web App开发
Python爬虫技巧:设置Cookie永不超时的详细指南
Python爬虫技巧:设置Cookie永不超时的详细指南
|
1月前
|
人工智能 监控 数据可视化
智慧工地一体化信息管理平台源码
智慧工地一体化平台融合大数据、AI、物联网等技术,构建覆盖人、机、料、法、环的数字化管理体系,实现施工全过程可视化、智能化管理,提升效率,推动建筑产业信息化升级。
294 4
|
2月前
|
人工智能 供应链 API
淘宝API商品详情接口全解析:从基础数据到深度挖掘
淘宝API商品详情接口不仅提供基础数据,更通过深度挖掘实现从数据到洞察的跨越。开发者需结合业务场景选择合适分析方法,利用AI标签、区块链溯源等新技术,最终实现数据驱动的电商业务创新。
|
6月前
|
前端开发 关系型数据库 RDS
购买RDS实例报错SLR 授权:未授权,应该怎么处理?
在阿里云购买RDS实例时,可能会遇到“SLR未授权”的报错。解决方法如下:1. 使用主账号登录控制台以确保权限充足;2. 在RDS购买页面选择正确的地域、引擎和产品系列,触发授权弹窗;3. 确认授权即可解决问题,若出现前端Bug导致报错,刷新页面即可。建议优先使用主账号避免RAM子账号权限配置复杂的问题。
311 29
|
5月前
|
API 开发工具 计算机视觉
YOLO11 语句整理
本内容介绍基于YOLOv11模型的开发流程,涵盖模型下载、安装依赖库、训练与推理、模型转换为OpenVINO格式及部署。通过Ultralytics工具包实现模型加载、训练和预测,并使用OpenVINO优化推理性能。此外,提供数据集划分方法,按指定比例生成训练集、验证集和测试集,确保数据准备规范化,提升模型训练效果与实用性。
|
9月前
|
Web App开发 JSON 前端开发
2.3K star!5分钟搭建专属网课平台?这个开源项目强得离谱!
嗨,大家好,我是小华同学。今天为大家介绍一款专为导师设计的开源视频会议系统——Nettu Meet。它具备实时音视频、共享白板、屏幕共享、聊天和文件共享等功能,特别适合在线辅导、艺术技能培训和语言学习交流等场景。用户可以轻松创建会议并自定义界面,提升在线教学效率和互动性。
190 1
2.3K star!5分钟搭建专属网课平台?这个开源项目强得离谱!
|
8月前
|
算法 数据安全/隐私保护
基于二次规划优化的OFDM系统PAPR抑制算法的matlab仿真
本程序基于二次规划优化的OFDM系统PAPR抑制算法,旨在降低OFDM信号的高峰均功率比(PAPR),以减少射频放大器的非线性失真并提高电源效率。通过MATLAB2022A仿真验证,核心算法通过对原始OFDM信号进行预编码,最小化最大瞬时功率,同时约束信号重构误差,确保数据完整性。完整程序运行后无水印,展示优化后的PAPR性能提升效果。
197 14
|
9月前
|
存储 人工智能 算法
《探秘AI绿色计算:降低人工智能硬件能耗的热点技术》
在人工智能快速发展的背景下,硬件能耗问题日益突出。为实现绿色计算,降低能耗成为关键课题。新型硬件架构如CRAM、自旋电子器件和量子计算硬件,以及优化的低功耗芯片设计、3D集成技术和液冷散热技术等,正崭露头角。同时,硬件与软件协同优化,通过模型压缩、算法适配等手段,进一步提升能效。这些技术将推动AI向更绿色、高效的方向发展,助力应对全球气候变化。
463 19
|
9月前
|
图形学
unity 物体震动
在Unity中实现物体震动效果,主要通过改变物体的位置、旋转或缩放属性来模拟震动。以下是位置震动的实现原理及代码示例:通过随机生成微小偏移量并累加到物体位置上,在短时间内不断改变位置产生震动效果。生成随机偏移,并结合时间控制持续震动。