Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: IoC object creation without importing Spring API

  1. #1
    Join Date
    Oct 2005
    Posts
    6

    Default IoC object creation without importing Spring API

    I apologize if this has been asked and answered, but I've been unable to find the solution. In short, I thought I could use Spring in my application without ever having Java code which imports classes from the Spring API.

    In my test class, I use the following code to access a bean, defined in
    applicationContext.xml.

    XmlBeanFactory mBeanFactory = new XmlBeanFactory(new
    ClassPathResource("applicationContext.xml", getClass()));
    TestObject test = (TestObject)mBeanFactory.getBean("testObject");
    String strSomething = test.getSomething();
    System.out.println("strSomething = " + strSomething);

    This works fine, in that strSomething has alreaady been injected, since it
    was specified in applicationContext.xml.

    However, I'm unsuccessful in setting this up in a servlet container. I used
    the same applicationContext.xml, and made reference to it from web.xml using
    the following:

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    <listener>
    <listener-class>org.springframework.web.context.ContextLoade rListener</lis
    tener-class>
    </listener>

    The part that I haven't figured out yet is how to access, get a new
    TestObject *without explicitly using the Spring API in code*. I presume its
    unlikely/unreasonable to expect that Spring, once loaded into the context
    (which does happen as confirmed in log files) will watch for any usage/request for a TestObject and
    instantiate as needed.

    But alas, I've searched far and wide, and only find reference to using through
    Struts/MVC style code which again, is coded to use the Spring API (e.g. WebApplicationContextUtils).

    Please help, is there a way to do this without having the dependency on Spring in Java (declaratively in XML is great, just not java).

  2. #2
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    In some cases your code will be dependant on Spring. If every object was created by Spring this problem would occur less, but not all objects are create by Spring, so some Spring specific code is required (access to the appcontext is required in those cases).

    And in most cases you will make use of functionality Spring provides, DAO support for example. So 100% Spring independant code is very unlikely.
    Last edited by Alarmnummer; Oct 25th, 2005 at 04:50 PM.

  3. #3
    Join Date
    Aug 2004
    Location
    Atlanta, GA
    Posts
    129

    Default

    At a minimum, you'll need to use org.springframework.web.context.support.WebApplica tionContextUtils to get the context and then retrieve the instance of your POJO.
    Randy

  4. #4
    Join Date
    Feb 2005
    Location
    Boston, MA
    Posts
    1,142

    Default

    You might be able to do this with AspectJ. You could try to create an aspect which would be called anytime a method which returns a TestObject was made from inside a method which was passed a ServletContext. It could use WebApplicationContextUtils to get the object from the ServletContext.

    Unfortunately I haven't studied AspectJ enough to sketch out what you would need to do that. Anybody else want to comment if this is possible?

  5. #5
    Join Date
    Jan 2005
    Posts
    15

    Default Method Injection

    Maybe I don't fully understand your problem, but if your object is created by Spring, you may use method injection (take a look at the docs).

    This way, Spring replaces an arbitrary method (say getMyBean()) by a method that retrieves objects from Spring, without you or your code knowing it.
    No import is necessary in this case, AFAIK.

    Regards,
    Esteve

  6. #6
    Join Date
    Oct 2005
    Posts
    6

    Default

    Quote Originally Posted by rstearns01
    At a minimum, you'll need to use org.springframework.web.context.support.WebApplica tionContextUtils to get the context and then retrieve the instance of your POJO.
    In essence, this is the part that I wanted to avoid. I recently attended a Java User's Group meeting where Justin Gehtland (co-author of Spring: A Developer's Notebook) gave a presentation on Spring. At any rate, I seem to recall he said you could have Spring inject dependencies without ever having to refer (import) directly to the Spring API in your Java code.

  7. #7
    Join Date
    Aug 2004
    Location
    Atlanta, GA
    Posts
    129

    Default

    Unfortunately, there has to be some "glue" code. An object instantiated via new, or through reflection, just won't have a handle to the factory/context, and since it wasn't created by the factory, it won't be injected. At some point, you must create, or at least get a handle to, a minimum of one bean that was created by the container. After that, you're in. I'm not aware of any way for an application to be entirely devoid of any Spring reference.
    Randy

  8. #8
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    Quote Originally Posted by athieme
    In essence, this is the part that I wanted to avoid. I recently attended a Java User's Group meeting where Justin Gehtland (co-author of Spring: A Developer's Notebook) gave a presentation on Spring. At any rate, I seem to recall he said you could have Spring inject dependencies without ever having to refer (import) directly to the Spring API in your Java code.
    When you create a class A that depends on class B, you can use Spring IoC to instanciate both A and B, set properties, and inject B instance into A instance. Neither B nor A need to know anything about Spring. But to use these two instances, you have to reference Spring API to access the ApplicationContext. The point is to minimize dependency on Spring API, but I beleive it is "not possible" to avoid it.
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  9. #9
    Join Date
    Aug 2005
    Location
    London
    Posts
    28

    Default

    athieme,

    I notice that you're in a web application so, from my experience, the key points to note are the entry points into your application - i.e. servlets, Struts actions, etc. and as long as they're managed by Spring then you shouldn't ever need to know about Spring's classes.

    Let's take a servlet filter as an example:

    Suppose you have the class TestFilter. Write this class as normal, wire it up in the bean config file and then use a DelegatingFilterProxy to handle the original request.

    As TestFilter is now a bean, inject its dependencies using setter methods, e.g. a TestObject, and viola, you have something similar to your original code without needing to go via a BeanFactory.

    There's similar support for Struts Action classes and probably other web frameworks but, strangely, there doesn't seem to be something like a DelegatingServletProxy but it's relatively easy to implement the principle (for example, I implemented delegating proxies for Struts's tile controllers).

    HTH,

    Cuong.

  10. #10
    Join Date
    Oct 2005
    Posts
    6

    Default

    Quote Originally Posted by cuong

    I notice that you're in a web application so, from my experience, the key points to note are the entry points into your application - i.e. servlets, Struts actions, etc. and as long as they're managed by Spring then you shouldn't ever need to know about Spring's classes.

    ...
    Thanks for the useful suggestion. I too have seen similar code for web applications. However, if I understand what you mean, this may only solve when the entry point is web app based. In fact, the code I am most concerned about, while technically running in JBoss, is decoupled from the app server. Ideally, I could find a solution which would be type safe (e.g. not requiring access to beans through a name/lookup/type cast convention) but also be extensible enough that I wouldn't need to define special methods for each class type.

Posting Permissions

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