tags:

views:

189

answers:

2

Hello guys,

I am in a tough spot and I cannot figure it out. I am using legacy code and we are migrating from PicoContainer 1.1 to Spring 2.5. I came across code where Pico grabs the abstract class and is able to invoke concrete methods. How can I do that in Spring?

This is what I tried in Spring so far:

<bean id="module" class="a.b.c.AbstractClass" abstract="true">
   <constructor-arg ref="aFactory1" index="0" />
   <constructor-arg ref="aFactory2" index="1" />
</bean>

As expected, when Spring injects this code, it cannot because the bean is Abstract.

If I could, I would use MethodInvokingFactoryBean, but that will not work as parameters are being invoked from another method which in itself is done by another bean.

How can I use Spring in a situation like this? Or should I try to push down the concrete methods defined in another class?

+2  A: 

More specifics would be helpful.

If you're invoking methods on an abstract class, there must be a concrete class somewhere that extends AbstractClass and implements the abstract methods; even if that concrete class is built by PicoContainer behind the scenes.

The simple thing to do is:

class ConcreteClass extends AbstractClass {
  // implement abstract methods
}

The bean would look like:

<bean id="concreteModule" parent="module"/>

You can invoke methods on the concreteModule bean.

If you're really daring, you could try method injection to inject the abstract methods directly into module. Remember to remove abstract="true". But I'm not totally sure if that will work.

dave
A: 

If I remember correctly, the abstract="true" in the following is saying that this is not an instantiable bean, but (in effect) a template for creating beans.

<bean id="module" class="a.b.c.Class" abstract="true"> 
   <constructor-arg ref="aFactory1" index="0" />
   <constructor-arg ref="aFactory2" index="1" />
</bean>

The way you use this is to define child beans; e.g.

<bean id="m1" parent="module"/>
<bean id="m2" parent="module">
   <property name="p1" value="42"/>
</bean>

This means that the child beans m1 and m2 will inherit the constructor argument definitions from module. The m2 bean will also have its p1 property set once it has been instantiated.

I think the class always has to be a concrete Java class name, because that is what you are telling Spring to instantiate. Clearly, Spring cannot instantiate an abstract class, or force specific arguments to be passed to the abstract class constructor.

Stephen C