ActFramework - 控制器单例还是多例

控制器是 MVC 框架的核心组件,应用程序控制器的方法处理 HTTP 请求。这里首当其冲需要回答的一个问题就是控制器的实例应该是单例 (Singleton)还是就每个请求生成新的实例。

不同的框架对此有不同的处理方式,SpringMVC 的控制器采用单例;Struts 的 Action 则是多实例;PlayFramework v1.x 的方式比较极端,控制器方法必须是静态的,因此不需要生成实例。

ActFramework 生成控制器实例的方式与众不同,没有统一的单例或者多例的限制,而是根据应用程序控制器代码来决定是否采用共享单例,还是就每个请求生成新的控制器实例。

1. 无字段的控制器 - 处理为单例

public class HelloController {
    
    @GetAction("/hello")
    public String sayHello() {
        return "Hello world!";
    }    
            
}

上面的控制器没有任何字段,因此对于任何发往 /hello 的请求,只会有一个 HelloController 的实例来响应。

2. 有字段的控制器 - 每个请求生成新的实例

public class LoggedInHelloController {

    @LoginUser User me;
    
    @GetAction("/hi")
    public String sayHi() {
        return "Hi from " + me.getFullName();
    }    

}

LoggedInHelloController 控制器有一个字段 User me,因此 ActFramework 认定这个控制器是有状态的,所以会对每个请求生成新的控制器实例。

3. 所有字段为无状态的控制器 - 处理为单例

@Entity("user")
public class User {...}

@Stateless
public class UserDao extends EbeanDao<User> {...}

@UrlContext("/users")
public class UserController {
    @Inject
    private UserDao userDao;
    
    @PostAction
    public User create(User user) {return userDao.save(user);}

    @GetAction
    public Iterable<User> list() {return userDao.findAll();}

    ...
}

上面的 UserDao 类被标注为 @Stateless,因此虽然 UserController 类中有 UserDao userDao 的字段,ActFramework 依然认定 UserController 是无状态的,所以所有请求响应会共享一个 UserController 实例

在类上标注 @Stateless 的方法非常简便好用,但当控制器中需要注入来自三方库的无状态对象,应用程序开发人员没有办法改变其代码,因此只能在使用的地方标注 @Stateless

public class SuperHelloController {
    @Stateless
    @Inject
    private HelloHelper helper;
    
    @GetAction("/superHello")
    public String superHello() {
        return helper.hello();
    }
}

SuperHelloController 中有一个 HelloHelper helper 字段,假设 HelloHelper 类来自三方库,而我们确信这个类和请求无关,因此标注该字段为 @Stateless,这样 ActFramework 会认定 SuperHelloController 为无状态的,所有请求共享一个 SuperHelloController 实例。

4. 总结

ActFramework 依据控制器的字段状态来判定是否对控制器做单例,或者多实例处理

  • 当控制器无字段时,控制器处理为单例
  • 当控制器有字段时:
    • 如果所有字段均有标注 @Stateless 或字段类型上有 @Stateless 标注,则处理为单例
    • 如果存在非 @Stateless 的字段,则处理为多实例

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏智能大石头

NewLife.Net——开始网络编程

网络编程的重要性就不说了,先上源码:https://github.com/nnhy/NewLife.Net.Tests

880
来自专栏Aloys的开发之路

VirtualBox相关问题总结

邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: ht...

1273
来自专栏逸鹏说道

并发编程~先导篇上

并发 :一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

1848
来自专栏草根专栏

使用Identity Server 4建立Authorization Server (6) - js(angular5) 客户端

由于手头目前用项目, 所以与前几篇文章不同, 这次要讲的js客户端这部分是通过我刚刚开发的真是项目的代码来讲解的. 这是后端的代码: https://githu...

5385
来自专栏草根专栏

使用Identity Server 4建立Authorization Server (1)

本文内容基本完全来自于Identity Server 4官方文档: https://identityserver4.readthedocs.io/ 官方文档很详...

46810
来自专栏张戈的专栏

Haproxy安装部署文档及多配置文件管理方案

最近我在负责一个统一接入层的建设项目,涉及到 Haproxy 和 ospf 的运维部署,本文分享一下我在部署 Haproxy 之后整理的运维部署规范,并实现了H...

74912
来自专栏bboysoul

如何黑入安卓手机(ezsploit)

安装很简单clone git clone https://github.com/rand0m1ze/ezsploit.git cd ezsploit ch...

1192
来自专栏Android机动车

Android BLE 快速上手指南

本文旨在提供一个方便没接触过Android上低功耗蓝牙(Bluetooth Low Energy)的同学快速上手使用的简易教程,因此对其中的一些细节不做过分深入...

1082
来自专栏py+selenium

linux 安装weblogic12.1.3.0步骤

需注意:fmw_12.1.3.0.0_wls.jar     需要jdk1.7.0_15以上的版本

5515
来自专栏张善友的专栏

实现WebSocket和WAMP协议的开源库WampSharp

Websocket Application Messaging Protocol 协议:https://github.com/wamp-proto/wamp-p...

2147

扫码关注云+社区