From what I can tell, Spring Stuff will never work with 7.0.0.beta1, because Vaadin has made a design change that inadvertently destroyed the very notion of a “Vaadin application”. There is no longer any entity with which to associate the Spring application context.
This has not been released yet… you will have to build this yourself (just run
ant jars ). Please file a bug if you encounter any problems so I can get them fixed in the next release.
Serialization/deserialization will not work… I’m still not sure how to properly fix that yet (see
these questions in the forum).
What is the advantage of using your Spring Addon vs using the @Configurable annotation (as described https://vaadin.com/wiki/-/wiki/Main/Spring%20Integration). Is there an advantage of one over the other? I can understand if one doesn’t have (or doesn’t want) AspectJ enabled in the project but if I am already using AspectJ (it is a Roo app), what advantage/disadvantage of using one method over the other?
Obviously with your Servlet based one, I don’t need to worry about remembering to add @Configurable(autowire=Autowire.BY_TYPE) to every class, but outside of that, is there an advantage for using the Servlet based concept vs the AspectJ annotation?
It depends on what beans you have and their lifetimes/scopes. @Configurable autowires “servlet scope” beans whereas @VaadinConfigurable autowires “Vaadin application” scope beans.
The Spring Stuff add-on creates an entirely new Spring application context, whose lifetime matches the lifetime of the Vaadin
Application instance (called
VaadinServiceSession in 7.x).
If the only Spring beans you define and need to autowire are “servlet scope” beans, then you don’t need Spring Stuff. For example, a singleton such as a DAO bean that is created once when the WAR file is loaded and which is shared by all Vaadin application instances.
On the other hand, if you have beans which are “Vaadin application scope” and you want to define and autowire those via Spring, then you need to use Spring Stuff. An example might be some event multicaster (such as for when a user logs in/out), per-user backend support stuff, etc.
Since Spring Stuff makes the servlet context the parent of the Vaadin application context, @VaadinConfigurable works for autowiring both types of beans.
So just to summarize if I understood correctly, if I want to use Request scope then I need Spring Stuff. If I only want to use “prototype” and/or “singleton” then I’m okay with the @Configurable annotations.
Request, prototype, and singleton scope are already-existing scopes that Spring provides. What is a “scope”? It’s just a place that beans live plus a specified lifecycle. The key is what is the lifecycle based on. For example, in a web application, singleton beans have scopes that match the lifecycle of the servlet context. Request scope beans have scopes that match the lifecycle of the HTTP request. Etc.
What Spring does not provide is a scope that matches the Vaadin Application lifecycle. Spring Stuff gives you this, in the form of an application context that gets automatically created along with each Vaadin application, and whose lifecycle matches that Vaadin application’s lifecycle. So a Spring bean in the Vaadin application context that’s marked
scope=“singleton” (the default) is actually scoped to the Vaadin application’s lifecycle, because that’s the scope of the overall application context.
The Vaadin application context is in turn configured to have the web application context as its parent. This is the way you would normally do things: more narrowly scoped beans can refer to more broadly scoped beans (e.g., a Vaadin container referring to a DAO bean), but typically not the reverse. You can do the reverse (e.g., a Vaadin application bean registering as a listener on a web application context bean), but that sets you up for a memory leak if the more narrowly scoped bean (the Vaadin application bean) doesn’t unregister itself when its scope (the Vaadin application) closes. This is what the
VaadinExternalListener class in Spring Stuff is for… to automate that unregistering operation so that you avoid a memory leak.
You would need to do this if for example you had an event multicaster in your web application context (with servlet context scope) and you wanted one of your Vaadin
Container beans (Vaadin application scope) to listen to its events. If you just register as a listener normally, then when your Vaadin application closes, the listener is still registered and so the Vaadin application will never get freed → memory leak.
Basically, Spring Stuff is all about proper scoping and avoiding memory leaks. If you don’t care about memory leaks then it’s probably not worth the trouble
Thanks for the reply Archie. It took me a while to understand your scoping problem until I realized that as per Vaadin terminology, a Vaadin application is launched for every session. However, that being said, it would seem to me that the memory leak that you are plugging with Spring Stuff is only a temporary - any locked memory caused my session pointers accessing application data would be freed once the session expires/terminates.
Do you have any examples of Vaadin/Spring apps that you have built that you can share? I’m struggling a little to figure out the best practices for using Spring in the Vaadin app - in normal application, I would be the equivalent of Window object/s, forms, etc using Spring and injecting them into the required classes, but it does not seem like that is the “right” methodology for Vaadin.
I have yet to find a good Spring/Vaadin example to look at.
You are correct in the sense that if you only have pointers from session to application, there is no memory leaked after the session is closed. In other words, references from a more narrow scope to a wider scope don’t cause memory leaks.
But typically you have pointers in the other direction as well. These pointers almost always take the form of registered listeners.
For example, consider a Spring multicaster event source for application events that lives in the usual Spring web application context. Now suppose you have a Vaadin widget that registers itself as a listener on this event multicaster, so that you can update your GUI when certain events occur in your application. Well, now you have a pointer from the web application context into the session, and when the session expires that pointer is still going to be there, preventing your session data (i.e., the widget and indirectly your entire Vaadin application) from being freed.
There are also other kinds of leaks, such as thread leaks. Suppose you need to create a thread in your Vaadin application that does something. You need to stop that thread when the Vaadin application closes, otherwise you are leaking both the thread and whatever else it points to.
Spring already provides nice lifecycle interfaces for handling this kind of stuff and much more (e.g., the
InitializingBean and
DisposableBean interfaces). The Spring guys understand lifecycle management and scoping and how to write applications that properly control their state. Spring Stuff just allows you to use all these tools and apply them at the Vaadin application level.
Did you look at the Spring Stuff
example code on github ? Other than that all my “real” examples are proprietary.
in my pom.xml, I am able to get the jar file. But it is unable to download a -sources.jar package. Have the sources for SpringStuff not been published as a Maven pkg along with the binary?
Not quite certain but if I remember correctly, nowadays Vaadin directory should also publish Maven sources and javadoc JARs if they are included (with the default names) in a ZIP-packaged add-on.
Thanks. I’ve downloaded the source code and am stepping in through it carefully, along with your demo app from github, but I’m a little uncertain about the purpose of the “Application Context XML File Location” (vaadinContextConfigLocation). I’m assuming that it is used to define the scoping of beans within the application context only vs the spring context. Does this mean that a “singleton” bean defined in the vaadinContext Config remains a singleton for the lifecycle of the application (ie: end of request)? Whereas a singleton bean defined in the standard spring context lives for the duration of the spring context - ie: until the webapp is shut down? How does it impact scopes such as “request” and “session”? I would assume that there would be no impact to a “request” scope but that a session scope defined in the vaadinContext would only be within the lifetime of a request, and consequently, not have much value.
Are these 2 completely independent configurations, or is the spring context a superset of the vaadinContextConfig? ie: do you really need to redefine context:annotation-config/ at the vaadinContextConfig level if it is already defined at the spring level?
In the case where a bean is defined in both the vaadinContext and the Spring Context, which scope does it follow when it is injected? For instance, if I have a bean annotated as @Component that is injected into a class, and both the vaadinContext and the springContext have annotation-scanning enabled, how can I ensure that the bean is following the app context and not the spring context?
Do I understand it correctly that the ThreadLocal Pattern (https://vaadin.com/wiki/-/wiki/Main/ThreadLocal Pattern) is already implemented in ContextApplication using HttpRequestListener and should not be implemented by developers (onRequestStart() and onRequestEnd() are final in ContextApplication) when using Spring-Stuff?
Yes that is pretty much correct. The reason
onRequestStart() and
onRequestEnd() are final is because of the
open-closed principle . Subclasses can override
doOnRequestStart() and
doOnRequestEnd() instead.
Originally Vaadin did not have current application, current request, or current response thread local variables. That is why
ContextApplication.currentApplication() , etc. were created.
In Vaadin 7.x this has been remedied by
VaadinServiceSession.getCurrent() ,
VaadinServletService.getCurrentServletRequest() , etc.