For what it’s worth I, too, have only found a limited use for session beans - in fact, just the one so far : an event bus for all views/presenters involved with a Vaadin Application. Note, not an web-application-wide event bus.
As far as I can see, everything else Spring configured is going to be a singleton.
The only thing I thought could be better about them is if they contained a very simple example of how you could wire Spring beans into more than just the Vaadin application. For example: how you would approach wiring Spring managed services into a Vaadin custom component.
Thanks for this clean example! I’m new to Vaadin and I’m going to integrate it into my web applications I’m developing for my company.
I’m already using Spring, but there’s a thing I don’t understand of your example (demo2.zip).
The question is: is it necessary to use AutowireCapableBeanFactory?
If Spring is correctly configured in applicationContext.xml, when you get the WebApplicationContext with WebApplicationContextUtils.getRequiredWebApplicationContext you should be able to extract the MyApplication bean directly from it, no? Provided all injection via annotation and so on was correctly activated in the applicationContext itself.
For what I know, since you get the Application object created and injected by Spring itself, you get all other dependent object from there.
I mean: you define a custom component, marked for injection (via annotation) or declared in applicationContext and injected into the main Application bean.
Then, you can get that instance directly from the main Application code, isn’t it? And all Spring facilities should work as expected, for example the @Transactional annotation.
I don’t doubt that there may be a simpler way to do this.
Here is my (limited) understanding: The problem is that Vaadin requires you to extend Vaadin’s ApplicationServlet, which knows nothing of Spring. Every time ApplicationServlet needs a new Application instance, it invokes ApplicationServlet.getNewApplication(). This happens many times during the course of your web server’s life. This is the point at which we create Application instances, not when the application context is created. So what we have to do is create the Application instance using Spring at that time. That’s what the current code does.
Now it may be possible to define your bean as a scope=“prototype” (or scope=“session” more correctly) bean in the application context and have the BeanFactory get the bean by name instead of creating it explicitly. Then all the wiring would be done normally and implicitly. But you would also have to explicitly declare your Application bean in the application context. I guess it’s 6 one/half-dozen the other.
But my question remains: why do you use AutowireCapableBeanFactory? Couldn’t you use directly WebApplicationContext, calling getBean() on it?
Ok, maybe I’m getting to the point. I thought you can activate (as you did) Spring’s AOP-based configuration and then declare which beans are managed by Spring with annotations. So, besides putting @Autowired onto MyApplication’s fields, declaring the whole class as a Spring’s bean (with @Component, for example).
Anyway, the only reason you used AutowireCapableBeanFactory is to construct and correctly inject the MyApplication object, without the need to declare it in the applicationContext.xml?
Correct. This is the first approach. In retrosepct, the second approach probably makes more sense and is more “Spring-like”, i.e., less of a hack. At the time I was just trying to make the dumb thing work
I see. Thank you. Please don’t misunderstand me: your example was illuminating, I was getting lost into all the documentations, javadocs and so on so you saved my weekend
I would expect that your Autowire servlet will be integrated directly into Vaadin distribution, in the main package or in an integration package, ready to use.
Here’s my take on Vaadin Spring integration
http://psponcoding.blogspot.com/2011/03/vaadin-spring-integration.html . Depending on who you ask, but it might be a bit cleaner approach. The cleanest way would probably require some modifications to the core Vaadin implementation as suggested in the article.
I’m noticing that all approaches here are calling directly (one way or another) the Spring applicationContext for getting their beans through explicit invocation of the injection process.
Could it be possible to have Spring create every Vaadin component? So the DI would be done by Spring itself, without helper classes.
The only one I see necessary is the first Application creation (because of the lack of component creation listener). For this there’s need of the AutowiringApplicationServlet.
But from there on, couldn’t Spring be enough? If the main application object has all its dependencies injected by Spring itself and the main bean is Spring manager, what is missing?
This got me wondering and indeed there is a simpler way to do it as described above. With this scheme, no AutowireCapableBeanFactory is necessary (just WebApplicationContext) and your Application bean is declared explicitly inside the Spring application context (with scope=“session” of course).
Hi,
Thank you guys for resources provided here, and thanks for samples also.
In what situation I need load time weaving?
Let’s say I have SomeScreen class extending VerticalLayout in my app.
I have defined my main Application class as session scoped bean as in provided examples, but I create instance of SomeScreen with constructor during application lifecycle (not as spring bean).
I want use my repository bean from root app context as property inside SomeScreen
I tried following without load time weaving it doesn’t work. I receive NullPointerException for repository.
@Configurable(preConstruction = true,dependencyCheck=true)
public class SomeScreen extends VerticalLayout {
@Autowired(required = true)
private SomeRepository repository;
In my experience with Spring I’ve never had occasion to use load time weaving, and moreover I’m not sure that I completely understand when or why it’s needed (that’s a statement about my own ignorance, not the usefulness of load-time weaving).
In any case, you should be able to figure out why your example doesn’t work by continuously morphing it into my example (demo3.zip) until it starts working.
Problem I encounter is that I can’t inject spring beans in any object except main application class.
I guess I need to define every object (mainly layouts) as spring bean? @configurable in such classes doesn’t work :(, but I see it works in SpringApplication sample app in vaadin incubator repository.