I have 2 JSF managed beans A and B and I need to expire/destruct/destroy A after 2 minutes and B after 5 minutes. I checked this related question Timing out from a bean, but it is expiring whole session. I do not want to expire whole session.
How can I achieve this with a custom scope?
Given that you're using JSF bean management facility (and thus not CDI, which would require a completely different answer), you can achieve this with
@CustomScoped. The@CustomScopedvalue must refer aMapimplementation in a broader, usually existing, scope.Something like:
As the
@CustomScopedannotation doesn't support passing additional arguments, setting the timeout can only be done via an additional custom annotation like below:Now, here's a kickoff example of how the
#{timeoutScope}looks like, including@PostConstructsupport (automatically) and@PreDestroysupport (manually):You see, it's session scoped and implements
Map. As to the scope, this way it's tied to a specific user session, not to the whole application. If you actually want to share the bean across all user sessions in the application, then make it application scoped instead. As to theMap, henever JSF needs to find a managed bean, it first triesget(). If it returnsnull(i.e. bean doesn't exist yet), then it will auto-create the managed bean instance and perform aput().Inside the
put(), it's a matter of extracting and calculating the timeout and store it in the map. Inside theget(), you just check the timeout and returnnullto indicate JSF that bean doesn't exist anymore. JSF will then simply auto-create it and come back atput(), etc.Do note that I'm using
System#nanoTime()instead ofSystem#currentTimeMillis()as the latter is tied to OS (operating system) time, not to hardware time (and it's thus sensitive to a.o. DST and enduser-controlled changes in time).