Menu

Maintaining reference to configured context

2003-08-30
2003-09-02
  • Steve Ebersole

    Steve Ebersole - 2003-08-30

    I am considering using Spring to manage various types of "environment" information that we currently have sprinkled throughout various xml files and resource bundles plus managing some "plugin" configuration based on that environment information.

    In general, if I understand it correctly, I need to obtain an instance of ApplicationContext through some means, like say ApplicationContext ctx = new ClassPathXmlApplicationContext( "app.xml" ).  But I was wondering, in J2EE containers, what the usual way to maintain referencability of that ApplicationContext once initialized such that all components can later find it?

    I'd like to avoid storage into JNDI if possible.  What are the best practices for this?

    TIA

     
    • Rod Johnson

      Rod Johnson - 2003-08-31

      Steve,

      The usual choices in J2EE are to attach to one of the following points provided by your container:

      1 - attach to ServletContext for all servlets to share. WebApplicationContextUtils provides support for this out of the box. Simple and great for small-medium size web apps.
      2 - have a hierarchy for each controller servlet. Spring MVC uses this, and it works well at Struts controller servlet level as well if using Spring with Struts MVC. Note that as each servlet has a hierarchy of configuration, the top level can be shared between all servlets. Ideal for complex web apps.
      3 - Have an XML bean definition file (or custom format definition) per EJB instance. This is supported out of the box by the ejb.support package hierarchy.

      BeanFactory/ApplicationContext objects aren't usually serializable, so I wouldn't recommend JNDI storage.

      A major motivation of Spring is to avoid the need to use singletons. As discussed in Chapter 4 of my book ("Expert One-on-One J2EE") the Singleton is often an anti-pattern.

      Regards,
      Rod

       
      • Steve Ebersole

        Steve Ebersole - 2003-09-02

        Thanks for the response.

        Let me clarify a bit.  I think what you said makes absolute sense for configurations specific to a given layer.  The environment piece I was talking about is a more controlled way of managing system properties.  This is information needed by a weblogic custom security realm (loaded by the bootstrap classloader) as well as a servlet app and an ejb app loaded in seperate containers.  I don't see a way around doing this as a singleton unless I want to perform the initialization three times in three different places.  Maybe you can see another way, though?

        Another sort of general usage question.  In your experience, has it been best to utilize spring by managing config files per component, or per layer?

        Thanks

         
        • Rod Johnson

          Rod Johnson - 2003-09-02

          Sounds like you do need a Singleton. It could load an XmlBeanFactory, taking location information from a system property or the like. The BootstrapBeanFactory class in the beans.factory.support package was intended to support such cases, although I'm currently considering dropping it as I'm not sure it's better than people implementing their own singleton if they really have to. (Look at the docs/functionality of that class and let me know if it's useful to you.)

          The problem is that if you use distribution, your singleton won't necessarily be available to a remote EJB container. So they'll have separate instances anyway. If you don't want distribution, consider using local EJBs instead of remote EJBs. As I say in "Expert One-on-One J2EE" and Martin Fowler says in "POEAA", don't be too eager to make web apps distributed. (But of course you could still end up with one instance on every node in a clustered environment; I guess if they're all configured the same that doesn't matter.)

          Regarding "per component" or "per layer," normally per component. For example, one per Spring controller servlet with Spring MVC (of course you may choose only to use one controller as in Struts 1.0, so this becomes one per layer). One per Struts controller servlet if you use Struts for MVC. One per EJB, supported out of the box by the EJB support package. I find that if I use EJB (which I seldom do in web apps) my EJBs are usually coarse-grained, so it makes sense for them to have their own namespace.

          Remember also that BeanFactories/ApplicationContexts are hierarchical. So two controller servlets can have their own distinct XML files that share the definitions in applicationContext.xml. This is a good solution to "layer-level" config.

          Regards,
          Rod

           
    • Steve Ebersole

      Steve Ebersole - 2003-09-02

      I did check out the javadocs for the BeanFactoryBootstrap class.  However, I could not figure out how to tell it where to find its configuration.  I'll take a look at the source for it and see if I can decode its usage there.  So it may be better that I just go ahead and implement a custom singleton to wrap the ApplicationContext.

      The only distribution strategy we would even consider would be for horizontal distribution, so I don't think that would be that big of a deal.  I wish we could make these components run in the same container space.  Transactions were the main impetus for us using session beans at all (did not know about Spring and its transaction support then) as we need XA transactions, and the support built into session beans with CMT is sooooooo convenient.  I just ordered your book last weekend (still waiting) and loved Fowlers book.  In fact most of our system was designed from concepts in his book.

      I did not quite follow how the ejb.support package helps out at all in generating an ApllicationContext, at least from the javadocs.  Maybe I need to dig into the source here also...  My ejbs are also extremely course-grained, so one-per-component makes a lot of sense.

      The only way I saw to implement hierarchical contexts, was through the use of the various constructors taking String arrays representing the different config files (I am assuming the hierarchy is based on the the positions within the array?).  Is there built-in support for defining this within the config files themselves?  Or is the usual approach to acheive this through the use of XML external entities?

       
    • Rod Johnson

      Rod Johnson - 2003-09-02

      Before replying to your post this morning I revised BeanFactoryBootstrap to improve the Javadoc. So please check the latest version in CVS (you can see it via "browse CVS" on SourceForge if you don't want the trouble of setting up a CVS client).

      It sounds like local SLSBs would be the best option for you.

      The ejb.support package actually provides a BeanFactory, not an ApplicationContext: look at extending AbstractStatelessSessionBean. BeanFactory is a superinterface of ApplicationContext and provides the most important methods so this shouldn't be a problem for you. It should meet your management requirements.

      XML entities won't create a hierarchy, just a text-mode include way of refactoring a particular file.

      The hierarchy is automatically created in the Spring MVC framework, but as you say it involves constructor usage elsewhere. The EJB support package allows custom creation of a bean factory, but the default implementation is to use a single XML file.

      Regards,
      Rod

       
    • Steve Ebersole

      Steve Ebersole - 2003-09-02

      I went to the source code of the ejb support package and understand its usage now.  Very nice.

      ViewCVS says it is currently running against a backup server.  Indeed the CVS version shown there is exactly the same as what I have local here.  However, it did given me a chance to check out the source and see now how it works.  After further looking I think I will just retofit my current singleton Environment class to utilize an XmlBeanFactory helper.

      Thanks a bunch for all your help...

       

Log in to post a comment.

MongoDB Logo MongoDB