前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ActFramework - 控制器单例还是多例

ActFramework - 控制器单例还是多例

作者头像
老码农
发布2018-06-27 10:34:57
2350
发布2018-06-27 10:34:57
举报
文章被收录于专栏:老码农专栏老码农专栏

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

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

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

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

代码语言:javascript
复制
public class HelloController {
    
    @GetAction("/hello")
    public String sayHello() {
        return "Hello world!";
    }    
            
}

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

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

代码语言:javascript
复制
public class LoggedInHelloController {

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

}

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

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

代码语言:javascript
复制
@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

代码语言:javascript
复制
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 的字段,则处理为多实例
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 无字段的控制器 - 处理为单例
  • 2. 有字段的控制器 - 每个请求生成新的实例
  • 3. 所有字段为无状态的控制器 - 处理为单例
  • 4. 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档