专栏首页老码农专栏ActFramework - 控制器单例还是多例

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 条评论
登录 后参与评论

相关文章

  • Actframework中如何灵活控制JSON响应

    老码农
  • ActFramework r1.2.0 带来的新特性

    老码农
  • Actframework依赖注入 II - 注入对象类型

    老码农
  • 程序员进阶之算法练习(二十五)

    前言 算法题是锻炼思维的好工具,在解决问题的层面考察思考能力。 正文 1. Compote 题目链接 题目大意: 给出a、b、c三种材料,可以1:2:4组成...

    落影
  • 讲一下Asp.net core MVC2.1 里面的 ApiControllerAttribute

    ASP.NET Core MVC 2.1 特意为构建 HTTP API 提供了一些小特性,今天主角就是 ApiControllerAttribute. (注:文...

    _淡定_
  • 孔乙己的疑问:单例模式有几种写法

    上面三种写法本质上其实是一样的,也是各类文章在介绍饿汉式时常用的方式。但使用静态final的实例对象或者使用静态代码块依旧不能解决在反序列化、反射、克隆时重新生...

    哲洛不闹
  • PHP反射类export方法详细解析

    CrazyCodes
  • (52) 抽象容器类 / 计算机程序的思维逻辑

    查看历史文章,请点击上方链接关注公众号。 从38节到51节,我们介绍的都是具体的容器类,上节我们提到,所有具体容器类其实都不是从头构建的,它们都继承了一些抽象容...

    swiftma
  • 设计原则

    一、面向对象应用程序开发原则(SOLID) 1单一职责原则(SRP) 定义: 一个类应该只有一个发生变化的原因。这条原则曾被称为内聚性,即一个模块的组成元素之间...

    甜橙很酸
  • 23种设计模式详解(六)

    南风

扫码关注云+社区

领取腾讯云代金券