Configure Spring Property of Subclass Field with Same Name as Parent's

897 Views Asked by At

Suppose I have the following classes:

package wild;

import moco.GeneralMovement;

public class Animal{

    protected GeneralMovement movement;

    public getMovement (){
            return movement;
    }
    public void setMovement (GeneralMovement movement){
            this.movement = movement;
    }
}

package sur;

import loco.QuadripedalMovement;
import wild.Animal;

public class Mammal extends Animal{

    protected QuadripedalMovement movement;

    public QuadripedalMovement  getMovement (){
            return movement;
    }
    public void setMovement (QuadripedalMovement movement){
            this.movement = movement;
    }

    public void test(){
            super.movement.move();
    }

}

package zoo;

import sur.Mammal;

public class Gorilla extends Mammal{

    public void doSomething(){
        test();
        movement.grove();
    }
}

package moco;

public class GeneralMovement {

  public void move(){
  System.out.println("Moving");
  }
}

package loco;

import moco.GeneralMovement;

public class QuadripedalMovement extends GeneralMovement{

    public void grove(){
    System.out.println("Grooving...");
    }
}

import zoo.Gorilla;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {

    private ApplicationContext ctx;

    public static void main(String[] args) {
        Test test =  new Test();
        test.doProcess();
    }
    public void doProcess(){
        String cfgFiles[] = {"zoo.xml"};
        ctx = new ClassPathXmlApplicationContext(cfgFiles);
        Gorilla gorilla = (Gorilla) ctx.getBean("Gorilla");
        gorilla.doSomething();

    }
}

Then the following XML config:

    <bean id="Gorilla" class="zoo.Gorilla">
        <property name="movement">
            <ref bean="QuadripedalMovement"/>
        </property>
    </bean>

    <bean id="QuadripedalMovement" class="loco.QuadripedalMovement" />
</beans>

The above would give a NullPointerException upon calling doSomething() movement.grove().

Moving
Exception in thread "main" java.lang.NullPointerException
    at zoo.Gorilla.doSomething(Gorilla.java:9)
    at Test.doProcess(Test.java:64)
    at Test.main(Test.java:49)

From what I understood from a little research this has something to do with Java not being capable of overriding fields. The above (please correct me if my understanding is wrong) would actually refer to two(?) different fields.

Why does the above code work when move() is invoked through using super keyword? Does this mean that Spring would assign the created QuadripedalMovement class to the parent field instead of the child's despite the class type being explicitly defined in the bean definition class attribute?

How do I configure spring to assign it to the (Mammal) subclass' field so I can reference it through an instance of Gorilla? I cannot modify the Java code for Animal and Gorilla. I can only modify the Mammal class. My temporary solution is to let Mammal implement InitializingBean and setting the value of movement there.

public void afterPropertiesSet() throws Exception {
  this.movement = (QuadripedalMovement) super.movement;
}

But I've only recently began to study Spring (and Java) so I don't know if this is correct (or good practice). Any help would be appreciated.

Note: The above code is the same structure as the code I am currently studying. I cannot provide the original. The version of spring used is 2.5.6

0

There are 0 best solutions below