Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: Access application context from code without servlet context

  1. #11
    Join Date
    Jul 2006
    Posts
    2

    Default Access application context from code without servlet context

    Bosman,

    Thanks for the quick reply.

    I endeavored to wire everything and I did use nothing but singleton instances, so I guess I've got the spirit but I think I need to rethink the design.

    Perhaps I've attempted to inject too much. Should I be injecting only those classes that can be singletons? Is that the gist of your suggestion that I redesign the services to be singletons?

    The nature of several of our services is that they are very stateful. In addition to database queries, they often must calculate statistics on the result set and then trim the results based on those statistics. Obviously, this requires some stateful accumulator objects that can't be singletons.

    I guess the question is, what should be spring injected and what shouldn't be spring injected? Should I look to injecting more factories rather than single instances of beans?

  2. #12
    Join Date
    Feb 2005
    Location
    Cambridge, UK
    Posts
    37

    Default

    In general, "vanilla Spring" is most suited to a design where those things which are injected are singletons. You should be able to rework your design such that either it consists of these entirely, or that the "stateful" beans are only one or perhaps 2 layers deep. Yes, as you mention, a key strategy is to remodel services as "factories" or even "factories of factories" in order to effect this transformation - Spring is set up to make this kind of thing quite idiomatic. If the resulting design is still too complex/messy, I do invite you to consider the request-scope injection approach :P

  3. #13
    Join Date
    May 2006
    Location
    Zug, Switzerland
    Posts
    89

    Default

    I've gotten this far: I've added a service/manager layer on top of my DAO classes, the DAO classes as well as the service beans are singletons. Essentially, the service layer represents business fuctions by packaging a sequence of DAO requests while taking the DTO bean to run the DAO methods on as argument.

    I then have defined "business" beans injecting a service bean reference, but these beans are prototypes. My UI components get an instane of these business beans. This seems to work well, as the prototyp beans are never injected into singletons.

    However, one thing I wonder about a comment from Bosman is:

    I.e. at the point you want to leave Spring behind
    How do my non-Spring beans access Spring beans if not by using the getBean() method? It is my understanding that the best way to go is to wire EVERYTHING together and not have a non-Spring part of code.

    Cheers and thanks all for their comments and help
    Simon

  4. #14
    Join Date
    Feb 2005
    Location
    Cambridge, UK
    Posts
    37

    Default

    Sneider - it looks like you have pretty much the correct standard pattern. Here is a more detailed explanation of the "non-Spring beans gaining access to Spring" issues:

    Any access to Spring beans must ("should") be done via Spring, i.e. via dependency injection. That is, if you have beans in your code which require Spring dependencies, but are created via a non-Spring creational pattern, the Spring dependencies must be injected into the creator/factory for these non-Spring beans, which it delivers to them via normal routes (e.g. via manually calling constructor arguments or calling setters).

    E.g.
    Code:
    public class NonSpringFactory {
      private LeafDependency leafdep;
      public void setLeafDependency(LeafDependency leafdep) {
         this.leafdep = leafdep;
          }
      public NonSpringBean createNonSpringBean() {
         NonSpringBean nonspring = new NonSpringBean(leafdep);
         return nonspring;
         }
      }
    So, NonSpringFactory is configured into your context as a normal Spring bean - LeafDependency is delivered to it via Spring. If for one reason or another (generally most likely as a result of lifetime issues) its product cannot be Spring-configured, and it has LeafDependency as a dependency within Spring, you must use Spring to deliver it to the "closest available point", i.e the nearest Spring-configured bean which in this case is NonSpringFactory. So "LeafDependency" is a "pass-through" dependency which is not a dependency of the Factory, but of its product. At no point should you ever call getBean().

    In more complex cases, this idea is the same, only there may be more than one layer of non-Spring creation between source and target, and it becomes increasingly onerous to ferry the dependencies. In Spring therefore the pressure is to de-state-ify your design by working as far as possible with stateless beans which can all be placed in the context, and allowing you to deliver the dependencies precisely to the target.

    Until Spring 2.0, the only support for non-singleton beans was as prototypes, which was unsatisfactory since these could not participate in any further injection. Note that now in Spring 2.0 there is support for arbitrary bean scopes, which will help in a lot of cases, although I suspect the 2.0 request scope will be too slow to be suitable for heavyweight work with the request. I will do further tests once we have a full release.
    Last edited by Bosmon; Jul 5th, 2006 at 08:01 AM.

  5. #15
    Join Date
    May 2006
    Location
    Zug, Switzerland
    Posts
    89

    Default

    Bosmon - thank you very much for your feedback. One question remains: If I have code wanting to use this NonSpringFactory, how does it get a reference to the factory? By injection? Or by standard Singleton-accessors (getInstance() et al.), assuming Spring has already initialized the bean (possible with lazy-init=false)?

    In the former case, I'd have Spring beans passing non-Spring beans between them. So there's no non-Spring layer, but merely non-Spring command objects.

    Generally, I feel Spring can sometimes replace the need for a factory. I started writing a DAO factory and injected the factory into each service bean, but dropped that approach in favor of passing concrete DAO beans into the corresponding service bean. Thus the factory code of deciding which bean to (create and) return was replaced by Spring context configuration.

    To me, the Spring context definition takes away the direct benefit of a factory. Both approaches "return" a bean instance, with the factory pattern you have to ask for it, with Spring you just get it.

    Cheers
    Simon

  6. #16
    Join Date
    Feb 2005
    Location
    Cambridge, UK
    Posts
    37

    Default

    Well, it's a bit of a conceptual shift, but you will (eventually/hopefully come to see the world turn round in such a way that you use Spring/IoC essentially for *everything*, and not worry about questions like "If I have code wanting to use this NonSpringFactory, how does it get a reference to the factory" - yes, the answer is always the same, "by Injection" :P The point is that Spring spreads "everywhere", like a virus - the real benefits of IoC only occur once it is spread across an entire design (the 80/20 rule - 80% adoption only gives 20% of the benefits).

    Singleton-accessors (getInstance()) are the old-fashioned, poor programming practice that Spring and in general IoC programming replaces.

    It's not that "Spring takes away the direct benefit of a factory", but actually disables the poorer programming practices that involve trying to use it directly. The ability to "ask for things" always creates a dependency, whereas "just getting them" removes it - since they could have been "just given to you" in practically any way (not even necessarily involving Spring, but in fact any IoC framework, or even manually, by code). Something that you can "ask for", you can get in only one way.

    As you're finding, with current Spring architecture, IoC has to generally "stop" at some barrier caused by a scope-change, but even this barrier can now be breached by more recent developments such as Spring 2.0's bean scopes, or RSF's request-scope beans.

  7. #17
    Join Date
    May 2006
    Location
    Zug, Switzerland
    Posts
    89

    Default

    Bosman, and everyone else who has contributed, thanks a lot for your valuable comments. Just as the last post of Bosman suggests, I've also come to the conclusion that there should be no "non-Spring" section/layer in an application if somehow possible.

    For me, that concludes this discussion.

    Cheers
    Simon

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •