将实例变量添加到Controller是错误的吗?

时间:2013-07-24 11:46:55

标签: grails scope grails-controller

如果我想在控制器中的多个方法之间共享一个对象,那么创建一个实例var是不对的? E.g。

class MyController {
    def index() {
        def user = verifyUserLogin()
        [messages:getMessages(user)]
    }

    private verifyUserLogin() {
        ...
        return user
    }

    private getMessages(user) {
        ...do something with `user`...
        return messages
    }
}

会变成

class MyController {
    private user

    def index() {
        verifyUserLogin()
        [messages:getMessages()]
    }

    private void verifyUserLogin() {
        ...
        this.user = user
        return
    }

    private getMessages() {
        ...do something with `user`...
        return messages
    }
}

3 个答案:

答案 0 :(得分:2)

Grails控制器不是为每个请求创建的单例,因此实例级变量不应该是任何问题。

但是我个人更喜欢不尽可能地声明实例级变量,因为当代码开始变得冗长时,很难弄清楚初始化和使用变量的代码流。

我宁愿选择将它们作为参数传递。然而,没有这样的经验法则,这在很大程度上取决于手头的问题。

答案 1 :(得分:0)

传统的方法 - 至少对于Servlet - 在控制器之间存储状态,即在请求之间传递信息是使用session对象。

class MyController(){
   def index(){
       session.user = getUser()
   }

   def postex(){
       def user = session.user
   }
}

答案 2 :(得分:0)

在grails 3.2.1中,控制器的默认范围从“prototype”(每个请求的控制器实例)变为“singleton”,每个控制器的一个实例。

除非你改变范围,否则这使控制器中的实例变量不再安全!

https://docs.grails.org/3.2.1/ref/Controllers/scope.html单身人士 https://docs.grails.org/3.2.0/ref/Controllers/scope.html原型

如果您确实想在控制器中使用实例变量,请更改范围static scope = "prototype"

您可以在请求上设置变量(作为请求属性),而不是使用实例变量。 request.user = user请注意,这些将在请求的生命周期内持续存在(对于请求遍历的所有拦截器和视图都可见)。