Oct 25th, 2005, 04:33 PM
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
XmlBeanFactory mBeanFactory = new XmlBeanFactory(new
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 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).
Oct 25th, 2005, 04:42 PM
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.
Oct 25th, 2005, 04:48 PM
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.
Oct 25th, 2005, 06:13 PM
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?
Oct 26th, 2005, 04:22 AM
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.
Oct 26th, 2005, 12:37 PM
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.
Originally Posted by rstearns01
Oct 26th, 2005, 05:39 PM
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.
Oct 26th, 2005, 09:27 PM
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.
Originally Posted by athieme
Oct 27th, 2005, 02:06 AM
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).
Oct 27th, 2005, 10:41 AM
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.
Originally Posted by cuong