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

相关文章

来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2142
来自专栏杨龙飞前端

scrollto 到指定位置

2494
来自专栏跟着阿笨一起玩NET

c#实现打印功能

2692
来自专栏闻道于事

js登录滑动验证,不滑动无法登陆

js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html...

6738
来自专栏张善友的专栏

Silverlight + Model-View-ViewModel (MVVM)

     早在2005年,John Gossman写了一篇关于Model-View-ViewModel模式的博文,这种模式被他所在的微软的项目组用来创建Expr...

2948
来自专栏java 成神之路

使用 NIO 实现 echo 服务器

4547
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

4828
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

5376
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3095
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2547

扫码关注云+社区