Spring 2.5 managed servlets: howto?
Correct me if anything is wrong.
As I understand, all Spring functionality, namely DI works when beans are got thru
Spring Context, ie getBean() method.
Otherwise, none can work, even if my method is marked @Transactional and I will
create the owning class with a new operator, no transaction management will be provided.
I use Tomcat 6 as a servlet container.So, my question is: how to make Servlet methods managed by Spring framework.
The issue here is that I use a framework, and its servlets extend the functionality of
basic java Servlets, so they have more methods. Still, web.xml is present in an app as usual.
The thing is that I do not control the servlets creation flow, I can only override a few methods
of each servlet, the flow is basically written down in some xml file, but I control this process
using a graphical gui.
So, basically, I only add some code to a few methods of each Servlet.
How to make those methods managed by Spring framework? The basic thing I need to do is
making these methods transactional (@Transactional).
comment to Bozho: @Bozho Let's see. In these servlets' methods I work with framework capabilities, let's say special variables that are got and saved in the current session. And what is needed, is looping through those framework-based collections while saving some values in a database. What you suggest is introducing a new very complex object, so that it could be passed to a service layer. (Service layer will not know anything about framework, its classes and objects kept in current Session! First, we "wrap" framework based collections to such a object, so copy everything into it. Then, again, the Service layer method should e开发者_Go百科ither save changes in a database or, worse case, return a new complex object so that Servlet framework method could update framework variables depending on the result of Service layer method execution. It is a workaround but do you think it is a good idea?You can also define your servlets directly in the Spring application context. You'll need a "proxy" servlet registered in web.xml
and delegating to the servlet instance which is configured as bean in the applicationContext.xml
. Proxy servlet is configured with the name of the target servlet bean, it discovers this bean via WebApplicationContextUtils.getRequiredWebApplicationContext().getBean(...)
and delegates all the processing to the target servlet. In this case an instance of your servlet is completely managed by Spring.
I'd suggest restructuring your code - making servlet methods transactional is not a good thing to do. Put the transactional logic in a separate, service class, and either
- obtain these spring-managed classes by
WebApplicationContextUtils.getRequiredWebApplicationContext().getBean(..)
or - in your servlet
init()
method obtain theApplicationContext
with the above method and callappCtx.getAutowireCapableBeanFactory().autowireBean(this)
. This way you can inject the transactional classes in your servlet as if it was spring-managed.
Now, you can do all this, but it is definitely not a beautiful way to go. I'd suggest using Spring MVC or any other MVC framework (which support spring integration of its components)
If this is all not possible, as a last resort I think you can use @Configurable
(on your servlets) with a <context:load-time-weaver/>
.
You should take a look how Spring proxy filters: http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.web/3.0.2/org/springframework/web/filter/DelegatingFilterProxy.java
In theory you could easily make the same sort of proxy for servlets and DispatcherServlet is sort of a proxy.
精彩评论