tags:

views:

228

answers:

3

I'm working with an incorrectly built spring application. Rather than use IOC, objects that require references are pulling their references from the context:

    BeanFactory b = SingletonBeanFactoryLocator.getInstance().
               useBeanFactory("factory").getFactory();
    Bean foo = (FOO)beanFactory.getBean("foo");

Putting aside the non-IOC design, what are the other detrimental effects of this? For example, does this have any particular performance implications? Is there any way that this could result in the creation of additional contexts or object references? Anything else really unpleasant that this could cause?

+1  A: 

One possible issue that came straight to mind is that if that code is used in a functional method instead of some initialization method, the bean gets re-fetched a lot which most likely slows things down.

That's not really maintainable either, if the name of the bean is changed all the references to it have to be updated by hand or nothing will work. This of course extends to beans which depend on other beans and maybe even those beans depend on other beans too, something like DataSource as bean to common JDBC Template for non-transactional database queries which is injected to a general-purpose container class from which all the other classes fetch such objects.

Esko
I sort of remember seeing references to this being slower, but if it's just (as is likely) getting a reference to some global map and pulling an object via a string key, it shouldn't be noticeable (I'm guessing). You're of course correct about maintainability - this is all so,so wrong anyway.
Steve B.
If the beans have the (default) scope of "singleton", than Spring will return the same instance for each call to getBean() - so the only repeated work will be Spring searching it's cache
matt b
+1  A: 

I believe the only real "performance concern" is the additional calls to getBean(); if this is called a very large number of times, it could have an impact. It's also important to consider how expensive the other operations in this context are: if you are doing something like querying a database or making a high-latency connection to another network, it probably won't be significant. But if this is happening in the context of a screen refresh in GUI programming then it could be very costly.

Any of the other features that Spring gives you (AOP, scoped beans, etc) are going to be behave the same way whether the object is injected or fetched from the container.

cliff.meyers
+1  A: 

The old phrase "you can program fortran in any language" comes to mind. Using spring as a service locator sounds like you're missing out on most of the things that make spring nice. Spring isn't really a pretty service locator either. It also makes it harder to make unit tests, since you loose some of the really nice loose coupling. (You're tightening the coupling in this way)

IMO these arguments alone enough are reason to convert. I wouldn't even start talking about performance, which others have pointed out are not really likely unless you're in some tight loops.

On the plus side, you can probably really easily convert to spring annotations, which is probably the reason the original author of your code didn't do the "correct" spring; he didn't like all the xml. With annotations you don't need all that xml.

krosenvold
Agree with all the architectural issues, more interested in creating motivation for refactoring. Unfortunately, the reason it was written this way was because the original authors didn't understand spring - I think someone wrote one instance of the above code, all else was just cut-n-paste. Sigh.
Steve B.
I was trying to say that just the testability alone should be reasonable motivation. But I know it's hard if you're not test driven. But I think you could *very* easily set up for a gradual conversion to annotations. Even easier than with "correct" xml based spring.
krosenvold