What are the differences between javax.faces.flow.FlowScoped and javax.enterprise.context.ConversationScoped beans and when should either be used in application? Becouse as far as I'm concerned they are somehow similar, but I can not figure it out by the material I found on the Internet?
A flow is a group of views related by navigation rules. Flow-scoped beans stay alive as long as you navigate within this flow, and they die when you leave the flow.
Conversation-scoped beans can also survive navigation, but their lifetime is delimited programmatically by calling Conversation.begin() and Conversation.end(). They are not directly related to a specific group of views.
You can use conversation scoped beans without using JSF.
Related
In Java Wicket 6, I'm trying to find out how to get notified in a Page or Component when that Page / component is no longer used.
The context is I have a configuration service that can have listeners added to it to notify when configuration has changed / reloaded.
Obviously, if a page/component is no longer needed then I should remove it as a listener from the service, but I can't find a way of being notified or that fact.
onRemove() doesn't cut it, as it doesn't appear to be called on the page or components in the page since I'm not explicitly REMOVING anything. I'm just letting pages/components drift away into the ether.
Any ideas on how I can clean up my resources to make sure my listener list / memory footprint doesn't balloon over a period of time?
My pages are stateful, btw (although I'm not sure they need to be atm). The Configuration Service is injected into a Page/Component via #SpringBean.
One possible way to propagate a configuration update it to have the page listen ONLY and then fire a Wicket event to contained components. This would cut down on the number of listeners to the Service, but this doesn't FEEL very nice if the components have a reference to the Configuration Service anyway to then be told by something else that it needs to reconfigure. Maybe.
Even so, with the above solution I'd still like to clear the Page from the listener list when no longer needed.
By using #SpringBean you do not make a hard reference between the Page/Component and the real service instance!
#SpringBean injects a (serializable) Proxy that has logic to lookup the Spring bean from Spring's ApplicationContext. So I think you have nothing to clean actually.
In JSF 2.0, the most obvious use-case for the view scope is a single page with potentially multiple AJAX post-backs. Using CDI instead of JSF managed beans leaves us without the view scope so we're either left to implement our own, use a (possibly bug-ridden) third party implementation or use the conversation scope.
My question: Is the conversation scope a worthy substitute for the view scope in the typical AJAX situation? Like the view scope, does it allow multiple instances per session? What are the pitfalls?
I'm aware of one of the pitfalls, namely that the conversation scope isn't automatically deleted when the user navigates away from the page, but instead is deleted after a time-out. But I'm not sure what happens when the user navigates back to that page before the conversation has timed out.
UPDATE
The conversation scope does indeed support multiple instances per session. This book states as much and I was able to confirm this using code from ch. 2.
In any #ConversationScoped CDI beans, you must have the following field:
#Inject
private Conversation conversation;
Whenever you want to begin the conversation, you need to check if the bean is in transient state. Otherwise, IllegalStateException will be thrown. It would be something like this:
public void beginConversation() {
if (conversation.isTransient()) conversation.begin();
}
By doing this, your bean will be in the long-running state. Hence, if the user navigate aways from the page and navigates back later on, you can always check if his conversation has timed-out or not and bring him to the page where he left.
Besides, I have been using #ViewScoped ManagedBean together with CDI bean for a while. You can still use #Inject to inject a CDI bean into a MangedBean. I don't think you can do the other way around though. Anyway, I have no idea if this would cause anything bad to happen later. However, up until now, I have never met any issues. If you really want to use #ViewScoped, I think you can try :P.
UPDATE:
Is the conversation scope a worthy substitute for the view scope in the typical AJAX situation?
I don't think #ConversationScoped can ever fully replace #ViewScoped.
Like the view scope, does it allow multiple instances per session?
No, you cannot have multiple instances per session. As I mentioned, if you start a new Conversation while the old conversation is still in long-running state, you will get IllegalStateException.
What are the pitfalls?
Well, one of the main advantages of #ViewScoped over #RequestScoped is that you don't need to re-initiate data every time the user submits the form to the same View. However, with #ConversationScoped, this advantage is over-used. While this problem is not as serious as if you use #SessionScoped, you still need to hold the initiated data as long as the #ConversationScoped bean lives. The longer the conversation, the more data you may need to hold.
I want to do something like this: index.xhtml -> createPerson.xhtml -> addAddress.xhtml -> index.xhtml.
In Managed-Bean CreatePerson a new Person-Object will be created, filled and saved, in Managed-Bean AddAddress I need the Person-Object in order to add an address to this person and after this, it should navigate back to the starting point. I think, the Managed-Bean CreatePerson should be #SessionScoped, because I have to inject the Person-Object into AddAdress (here #ViewScoped).
I want to have a loop or rather the possibility to create more than one person, but how can I do this if I have a SessionScoped-Bean, that lives longer than I need it? Is there any command or annotation to destroy it? How do you handle such workflows related to the scopes?
I know about MyFaces Orchestra with conversation-scope, but I will, if possible, do it only with Eclipse/Tomcat (7.0.11)/Mojarra (2.0.3).
Use a single view and make use of the rendered attribute to show/hide included views with "subforms" depending on each other. This way you can go with a #ViewScoped bean.
Alternatively, just save the Person in the DB after create and pass its id as request parameter to the next view and let it load from the DB again.
If you only want (or can) use Tomcat and Mojarra then both solutions mentioned by BalusC work perfectly, although with the limitations that you have to stay on a single page or redo queries between page navigation. Your use case is exactly what the conversation scope in Java EE 6 (through CDI) is made for. You can add this too to Tomcat via the Weld reference implementation.
When using the method BalusC outlined for staying on a single page, to give the user a tiny bit the impression of dealing with separate pages, it might be an option to display the rendered parts of the page using 'dialogs' (floating, css, ...). If using a third party component library is an option for you, you could add RichFaces or PrimeFaces that both contain ready to use dialog components.
Anyone know of any other custom spring scopes than Servlet Context Scope and ThreadScope ?
If you've made some closed-source custom scope I'd really also be interested in hearing what it does and how it worked out for you. (I'd imagine someone would make a WindowScope in a desktop app ?)
I'm open to all use cases, I'm looking to expand my horizon here.
We implemented our own custom Spring scope. A lot of our code works at a relatively low level, close to the database, and we maintain a conceptual level on top of that with its own object model of data sources, links, attributes etc.
Anyway, a lot of beans require a so-called StorageDictionary (an encapsulation of this object graph) to do their work. When we make non-trivial changes to the object graph, the dictionary sometimes needs to be blown away and recreated. Consequently, we implemented a custom scope for objects that were dictionary scoped, and part of the invalidation of a given dictionary involves clearing this custom scope. This lets Spring handle a nice form of automatic caching for these objects. You get the same object back every time up until the dictionary is invalidated, at which point you get a new object.
This helps not only with consistency but also allows the objects themselves to cache references to entities within the dictionary, safe within the knowledge that the cache will be valid for as long as they themselves are retrievable by Spring. This in turn lets us build these as immutable objects (so long as they can be wired via constructor injection), which is a very good thing to do anyway wherever possible.
This technique won't work everywhere and does depend heavily on the characteristics of the software (e.g. if the dictionary was modified regularly this would be horribly inefficient, and if it was updated never this would be unnecessary and slightly less efficient than direct access). However, it has definitely helped us pass off this management of lifecycle to Spring in a way that is conceptually straightforward and in my opinion quite elegant.
In my company we've created two custom scopes, one that will use Thread or Request and another that will use either Thread or Session. The idea is that a single scope can be used for scoped beans without having to change configuration based on the execution environment (JUnit or Servlet container). This also really comes in handy for when you run items in Quartz and no longer have a Request or Session scope available.
Background:
I work on a single web app that runs 4 different web sites under the same servlet context. Each site has its own domain name, e.g. www.examplesite1.com, www.examplesite2.com, etc.
Problem:
Sites sometimes require their own customised instance of a bean from the app context (usually for customised display of messages or formatting of objects).
For example, say sites 1 and 2 both use the "standardDateFormatter" bean, site 3 uses the "usDateFormatter" bean and site 4 uses the "ukDateFormatter" bean.
Solution:
I'm planning on using a "site" scope.
We have a Site enum like this:
enum Site {
SITE1, SITE2, SITE3, SITE4;
}
Then we have a filter that stores one of these Site values in the request's thread using a ThreadLocal. This is the site scope's "conversation id".
Then in the app context there'd be a bean named "dateFormatter", with 'scope="site"'. Then, wherever we want to use a date formatter, the correct one for the user's current site will be used.
Added later:
Sample code here:
http://github.com/eliotsykes/spring-site-scope
Oracle Coherence has implemented a datagrid scope for Spring beans. To sum it up:
A Data Grid Bean is a proxy to a
java.io.Serializable Bean instance
that is stored in a non-expiring
Coherence Distributed Cache (called
near-datagridbeans).
Never used them myself but they seem cool.
Apache Orchestra provides SpringConversationScope.
In a Spring Batch application, we have implemented an item scope.
Background
We have lots of #Service components which compute something based on the current batch item. Many of them need the same workflow:
Determine relevant item parts.
Init stuff based on the item.
For each item part, compute something (using stuff).
We moved the workflow into a base class template method, so the subclasses implement only findItemParts(Item) (doing 1 and 2) and computeSomething(ItemPart) (doing 3). So they became stateful (stuff initialized in findItemParts is needed in computeSomething), and that state must be cleared before the next item.
Some of those services also involve injected Spring beans which are also derived from the current item and must be removed afterwards.
Design
We implemented an AbstractScopeRegisteringItemProcessor which registers the item and allows subclasses to register derived beans. At the end of its process method, it removes the item from its scope context, and the derived beans using DefaultSingletonBeanRegistry.destroySingleton.
How it worked out
It works, but has the following problems:
We did not manage to get the derived beans cleaned up without registration (just based on their #Scope). The concrete processor must create and register them.
AbstractScopeRegisteringItemProcessor would have been nicer using composition and dynamically implementing all interfaces of the underlying processor. But then the resulting #StepScope bean is a proxy for the declared return type (i.e. AbstractScopeRegisteringItemProcessor or ItemProcessor) without the required callback interfaces.
EDIT
With the aid of #Eliot Sykes's solution and shared code plus #Cheetah's BeanDefinition registration, I was able to get rid of the registration as singleton beans. Instead, ItemScopeContext (the storage used by both the processor and the Scope implementation; Java-configured via a static #Bean method) implements BeanDefinitionRegistryPostProcessor. It registers a FactoryBean whose getObject() returns the current item or throws an exception if there is none. Now, a #Component annotated with #Scope(scopeName = "Item", proxyMode = ScopedProxyMode.TARGET_CLASS) can simply inject the item and need not be registered for end-of-scope cleanup.
So in the end, it did work out well.
A spring locale scope based on the users locale wihtin a web application
See related wiki page
In my company, we have also implemented spring custom scope. We have a multi tenant system where every customer can customize settings. Instance based scope of ours, caches the beans which are customer specific. So each time user of a customer logs in, these settings are cached and reused again when other users of the same customers sign in.
I once used a kind of conversation scope to store some objects in the session scope, in order to keep them when re-entering the same page, but limited to a single page to avoid to leave useless objects in the session. The implementation just stored the page URL and cleaned the conversation scope on each page change.
I got pretty big webflow definition, which I do not want to copy/paste for reusing. There are references to action bean in XML, which is kind natural.
I want to use same flow definiton twice: second time with actions configured differently (inject different implementation of service to it).
Is there easy way to do this?
Problem is I want to use same flow with different beans at once, in the same app. Copy/Paste is bad, but I dont see other solution for now.
You could try creating a new flow that extends the "pretty big one" and adding flowExecutionListeners to it.
The interface "FlowExecutionListener"defines methods for the following events in flow execution:
requestSubmitted
requestProceessed
sessionCreating
sessionStarting
sessionStarted
eventSignaled
transitionExecuting
stateEntering
viewRendered
viewRendering
stateEntered
paused
resuming
sessionEnding
sessionEnded
exceptionThrown
You can write a handler that injects the required resources to your flow (and use different handles with different flows) by storing it in the RequestContext, where you can access it in your flow definition.
Note that in that case you would still have to modify the "pretty big flow" to use those resources instead of referencing the beans directly.
I'm in the same fix that you're in...i have different subclasses which have corresponding action beans, but a lot of the flow is the same. In the past we have just copied and pasted...not happy with that!
I have some ideas I am going to try out with using the expression language. First, I came up with an action bean factory that will return the right action bean to use for a given class, then i can call that factory to set a variable that i can use instead of the hard-coded bean name.
Here's part of the flow:
<action-state id="checkForParams">
<on-entry>
<set name="flowScope.clientKey" value="requestParameters.clientKey"/>
<set name="flowScope.viewReportBean"
value="reportActionFactory.getViewBean(reportUnit)"/>
</on-entry>
<evaluate expression="viewReportBean"/>
The evaluate in the last line would normally refer directly to a bean, but now it refers to the result of the "set" I just did.
Good news--the right bean gets called.
Bad news--anything in the flow scope needs to be Serializable, so I get a NotSerializableException--arggh!
I can try setting something on a very short-lived scope, in which case it will need to get called all the time...or I can figure out some kind of proxy which holds the real bean as a proxy declared "transient".
BTW, I am using Spring 2.5.6 and webflow 2.0.7. Later versions may have better ways of handling this; in particular, EL's have gotten some attention, it seems. I'm still stuck with OGNL, which is the Spring 1.x EL.
I'm sure some webflow guru knows other ways of doing things in a less clunky fashion...
I don't think you can use the same webflow definition with the actions configured in two different ways.
If you want to use different actions you'll either have to reconfigure your action beans then redeploy your app or create a separate webflow definition with the differently configured beans.
This is a great Spring WebFlow resource.
Try to refactor the common configurable part in a subflow, and call the subflow from the different main flows where you want to reuse it.
Pass parameters to the subflow to configure it in any way needed, using the spring expression language to pass different spring beans, etc.