This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

IoC object creation without importing Spring API

Oct 25th, 2005, 04:33 PM

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.

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).

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.

Comment

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?

Comment

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.

Comment

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.

Comment

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.

Comment

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.

Comment

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.