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 的保护上面下功夫。

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

相关文章
|
6月前
ProcessViewer组件没有加载的问题,提示For recursive components, make sure to provide the “name“
ProcessViewer组件没有加载的问题,提示For recursive components, make sure to provide the “name“
46 0
|
Java 开发者 Spring
Arch. Components 2(二)|学习笔记
快速学习 Arch. Components 2(二)
Arch. Components 2(二)|学习笔记
|
存储 消息中间件 SQL
Arch. Components 1(二)|学习笔记
快速学习 Arch. Components 1(二)
113 0
Arch. Components 1(二)|学习笔记
|
存储 Java 应用服务中间件
Arch. Components 2(一)|学习笔记
快速学习 Arch. Components 2(一)
Arch. Components 2(一)|学习笔记
|
存储 缓存 前端开发
Arch. Components 1(一)|学习笔记
快速学习 Arch. Components 1(一)
105 0
Arch. Components 1(一)|学习笔记
Devexpress VCL Build v2014 vol 15.2.3 发布
2016年第一个版本,继续修补。 New Major Features in 15.2 What's New in VCL Products 15.2 Breaking Changes To learn about breaking changes in this version, ple...
1166 0
|
Shell Windows 数据格式
Devexpress VCL Build v2015 vol 15.1.2发布
2015年马上过半年了。终于第一个大版出来了。 What's New in 15.1.2 (VCL Product Line)   New Major Features in 15.1 What's New in VCL Products 15.
996 0
Devexpress VCL Build v2014 vol 14.2.7发布
2015年马上快过去一半了,这个玩意还在纠结在14版。其实也无所谓,反正就是改成15版,也还是这些 东西的修补。 What's New in 14.2.7 (VCL Product Line)   New Major Features in 14.
1172 0
|
容器
Devexpress VCL Build v2014 vol 14.2.6 发布
终于支持XE8 了。需要这么长时间吗? New Major Features in 14.2 What's New in VCL Products 14.2 Feature Highlights To learn about feature highlights in this versio...
1051 0
|
OLAP
Devexpress VCL Build v2014 vol 14.2.5 发布
和xe8 几乎同一天出来,但是目前官方不支持xe8. The following sections list all minor and major changes in DevExpress VCL 14.
1318 0