Reputation: 2290
Looking at Grails 3 documentation, the following is written about scopes:
prototype (default) - A new controller will be created for each request (recommended for actions as Closure properties)
The odd part here is that I get significantly different results in Grails 3.1.4 if I explicitly state:
static scope = "prototype"
Take for example the following UserController
class UserController {
def userService
List<String> users
def loadUsers() {
if (!users) {
println("########## have to load users");
try {
user = userService.getAllUsersInAd()
} catch (Exception e) {
// do something
}
} else {
println("########## dont have to do it " + users.size());
}
}
}
And the following UserService
class UserService {
def getAllUsersInAd() {
println("######### querying")
return new ArrayList<String>();
}
}
If static scope is omitted:
When I close a Firefox browser and re-open it, "dont have to do it is executed", regardless of how many times I close/reopen it. What is even more weird about this is that I can open a completely different browser (like chrome) when I close Firefox, and the same message executes. It is almost as if the scope of this controller is a similar one to @ApplicationScope of JSF. After a good 5-10 mins of idle time, the query is executed again, but the scenario remains.
If static scope is stated:
After each browser closing, the "have to load users" is executed as expected.
My question is, is the documentation wrong for the default scope? If it is not, what is the difference between explicitly stating scope="prototype" and omitting it(aside from the obvious above) ?
Upvotes: 1
Views: 646
Reputation: 14642
Yes, I believe controllers were changed to singleton (application) scope by default a while ago (version 1.4.x as it happens). I'm trying to find documentation of that. It seems it was a JIRA issue fix, originally here, but Grails has moved away from JIRA, and didn't migrate all the bugs to GitHub.
You shouldn't have state in controllers anyway according to the Grails team: Why does Grails recommend singleton scope for controllers with actions as methods? See Burt's answer, and Jeff even speaks up in the comments.
EDIT: As Jeff says, the default is still prototype, but the default generated config changes them all to singleton, which is recommended.
Upvotes: 1
Reputation: 27200
In the default generated application.yml
file for a Grails 3.1.4 app you should see a setting like this:
grails:
controllers:
defaultScope: singleton
That tells the framework to make controllers singleton. The default scope is prototype
if that setting is not set.
Upvotes: 3