tags:

views:

146

answers:

2

Hi,

I want to be able to call Interfaces in my class, but have spring instantiate them with the right implementation class behind the scenes.

I.e. Normally you can do:

IClass clz = new Class();

I want to have the line IClass clz; preferable in the middle of a method (or as one of the attributes if it can't be done), where clz is instantiated to the class I want by Spring.

The reason I'd like to do it this way is because I want to be able to be able to change which implementation I want to use simply by editing the context files.

Even better, would be knowing how to do the above with class contructors that expect parameters. i.e. new Class(ar1, arg2);

I hope this makes sense. Any help would be much appreciated.

+1  A: 

You can make your class implement BeanFactoryAware and then Spring will inject the bean factory in your class. If you then want to get an instance of a class implementing your interface you say something like:

beanFactory.getBean(IClass.class);

If there are multiple beans that implement the same interface you will have to resolve by name. To create a new object each time you ask this, set the bean scope of the bean you're asking for to "prototype".

Gerco Dries
A: 

You can include code such as:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
IClass clz = (IClass) context.getBean("beanName");

Not saying this is better per se than Gerco's answer btw, just it's an option, depending what you want to do.

You can also implement the ApplicationContextAware interface: I've found that using ApplicationContext gives me beans with filled-in properties, e.g. if you have an app.properties file which contains key/value property pairs which you expect to be resolved within the Spring config, beans retrieved via BeanFactory calls may not resolve those.

See this previous SO topic for more info.

Brian
As long as you create an ApplicationContext in your code, Spring will resolve the properties, placeholders, etc and pass you a reference to the ApplicationContext in setBeanFactory(). Every ApplicationContext is also a BeanFactory so BeanFactoryAware will work fine when all you need is getBean(). If you also want to access other methods that *are* application context specific, use ApplicationContextAware.
Gerco Dries
True but ApplicationContext is probably safer to use in general. I can never really remember the details to this - one of those things you work it out once then it all "just works" from that point. Reading background about it again though I do notice that the Spring docs themselves http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#context-introduction-ctx-vs-beanfactory now advocate: use ApplicationContext rather than BeanFactory unless you have a reason not to.
Brian
Is it possible to use propertyplaceholders, but pass the values needed at run time?
babyangel86 - pretty sure you can override them at runtime, yes. Remember Spring objects are still just objects - you can always call setXXX() methods after you retrieve them from your ApplicationContext. It probably does need to be a 2 step operation though: step 1 being get your object, step 2 being setting any new desired values.
Brian
Thanks guys. A combo of both ur solutions was what the dr ordered!