Announcement Announcement Module
Collapse
No announcement yet.
Servlet DI Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Servlet DI

    I am going to be migrating a servlet based web application to use Spring. I was hopeing to be able to use Spring to inject dependancies into my servlet, without my application needing to know about Spring. It appears that Spring does not provide a mechanism for this.

    The closest I could find was the org.springframework.web.context.support.ServletCon textAttributeExporter class. I used it to push the beans that the servlet needs into the ServletContext. Then have the servlet pull them out. This is not bad and it made unit testing easier, but it's not quite what I want to do.

    It seems like it would be fairly straightforward to use the same mechanism to inject beans into the servlet, since the servlet can be obtained from the ServletContext. It seems like it must have been a conscious decision not to implement this. I like the idea of IoC and DI, I don't like the idea of tying my servlet to Spring or any other framework, other than the servlet container.

    Why does Spring not support injection of dependencies directly into servlets? Was it a conscious decision? A technical impossibility? An oversight?

  • #2
    You can call WebApplicationContextUtils.getWebApplicationContex t(ServletContext), get the bean factory, cast it to AutowireCapableBeanFactory (which is safe) and call autowireBeanProperties on the servlet. This will give you setter injection.

    Direct injection of Servlets is not supported out of the box primarily because these days it's pretty rare to write much code directly in servlets, and generally it's best to use a web framework, which provides a much better architectural structure.

    Comment


    • #3
      I don't agree, I think there are plenty of developers who are skilled at writing good servlets and not willing to invest in a web framework at this point. There are too many options and not enough standards. I try to keep my applications from being coupled with frameworks, which hopefully makes them a bit more flexible.

      I am finally sold on the idea of DI, which is why I am looking to Spring to provide that functionality. I'm a bit dissapointed though that if I want to work Spring into my web applications, I am going to need to dive in head-first. It seems to me that requiring applications to import Spring framework classes to play DI defeats the purpose of DI!

      Comment


      • #4
        Looked at another way, Rod's reply is that your servlets should not have too much code, they should delegate to something else, such as POJOs. A framework just makes this much easier to do. Further, this would make unit testing easier and allow DI on the objects the servlets call upon.

        Comment


        • #5
          Understood, I follow patterns that keep the code in my servlets limited to view/controller logic. The servlets delagate business tasks to POJOs. Part of what I was hoping from Spring was to be able to link those POJOs to the servlets using DI. I wanted to use Spring to 'bootstrap' the web-application by linking everything together, which would make unit testing much easier because the unit tests could simply send in mock objects.

          The problem I found was that there is no way to reference a servlet in the application context XML file. I assumed that servlets would be accessable just as other beans are. Knowing that Spring is a mature framework, this seemed like it must be an architectural decision, rather than a 'to be developed' component.

          There seem to be a few 'workaround' methods for injecting beans into servlets, but no direct support without creating dependencies on Spring objects within application code, which to me seems even worse than putting business logic in servlets! I would like to break up my application and use a DI framework to assemble it at runtime. I'm not yet interested in binding my application to a specific framework.

          Comment


          • #6
            Originally posted by berniedurfee
            I'm a bit dissapointed though that if I want to work Spring into my web applications, I am going to need to dive in head-first. It seems to me that requiring applications to import Spring framework classes to play DI defeats the purpose of DI!
            The problem is that something has to *do* the dependency injection, either "manually", or via some "container" which does it for you. Spring does provide a container, or factory to do this, but it can only automatically wire up beans that it is responsible for creating. This is a technical constraint; how can anything wire up something you instantiate? With the golden age of AOP around the corner this will change, but for the moment, if *you* create them, *you* have to wire them up.

            If you don't want to use Springs factory and don't want to have Spring imports in your servlet then you could try hooking into the servlet container's code which instantiates servlets and doing the wiring up at that point, but that is just too horrible for words

            To be honest, I don't think you will find the Controller interface too objectionable. All your inhouse servlet skill is just as applicable when using Controllers.

            Comment


            • #7
              I don't think that is a technical constraint. Spring is already able to work with servlet containers through the servlet API. I believe that this would allow Spring to retrieve the servlet instance managed by the servlet container, at which point Spring could perform the DI tasks outlined in the application context file. Doing so would give existing web applications an easy way to slowly migrate to the other features of Spring, without immediately investing in Spring. It just seems like Spring is a bit too invasive for people considering migration.

              Comment


              • #8
                Hmm, interesting point

                One problem I see is *where* does Spring do it's work? Ideally you would want it when it is first defined, maybe via a ContextLoader, but how would you get hold of all the available servlets?

                It couldn't be in a filter because firstly you only want to happen first time, and secondly servlets are multithreaded so the filter would need to synchronise which would be *awful*

                Comment


                • #9
                  Good point, without the getServlet() method, I guess there is no good way for Spring to get an instance of a servlet to perform the DI. So I guess the best and only way to get something to a servlet is through the ServletContext. I suppose it is a technical limitation of the servlet specification after all.

                  Comment


                  • #10
                    I am not sure *when* the Spring servletContext gets initialised, otherwise I would suggest you write a base class which all your Servlets extend with the following code:

                    Code:
                    public abstact AbstractSpringAwareServlet implements Servlet {
                      public final void init(ServletConfig config) {
                        ServletContext ctx = config.getServletContext();
                        .. do the spring binding stuff here
                        onInit(config);
                      }
                      protected void onInit(final ServletConfig config) {
                      }
                    }
                    It might work, don't know

                    Comment


                    • #11
                      Yep, sounds like a good use for AOP. Although it would be nice if the Servlet spec gave some support to DI in the near future.

                      Comment


                      • #12
                        Why, when you have the fantastic Spring

                        Only kidding, I do take your point.

                        Comment


                        • #13
                          Did the abstract Servlet work, or have you not tried it?

                          Comment


                          • #14
                            Haven't tried it. I'm going to stick with pushing beans into the ServletContext and then pulling them out in the servlet. Perhaps as I migrate further into Spring I use more of the framework features.

                            Comment


                            • #15
                              Cool.

                              Please feel free to ask as many questions as you like

                              Spring is an excellent resource of best practice and these forums are very very friendly.

                              If you find a better way of doing something, please post it here, you will find many experts, and none of them are "Spring sales people"

                              Comment

                              Working...
                              X