Monday, April 18, 2011

Spring Parent Class Member Not Injected When Loading Child Class

If Class B extends Class A where B calls a method in parent A that will access propertyOfA, the assumption is that when B is loaded all property of parent A will be injected automatically because B extends A.
However, that' s not the case.  If you do not inject A's property in child class B, they will not be injected and you will get NullPointerException...
Thus, you should always inject parent's member if you are going to access them either directly or indirectly.... that sounds awkward.  Am I missing something here?
[July 27, 2011 Thanks to Luca for the correction] 
In fact, in order to have the inheritance happen in Spring bean declaration, you must explicitly declare the parent class in the bean definition.

Example: Class B extends Class A, in order to access A's property, B must inject in its definition as well.

// Parent Class
public class ClazzA {
  private Clazz propertyOfA;

  protected void methodOfA(){
    propertyOfA.invokeSomething();
  }
  public Clazz getPropertyOfA(){
    return this.propertyOfA;
  }
  public void setPropertyOfA(Clazz propertyOfA){
    this.propertyOfA = propertyOfA;
}

// ClazzB is sub-class of ClazzA
public class ClazzB extends ClazzA{
  protected void methodOfB(){
    methodOfA();
  }
}

// Member property type for ClazzA
public class Clazz{
  public void invokeSomething(){
    System.out.println("Invoke Clazz to do something!");
  }
}


In order for B to access parent A's property, B must declare parent="classA" in its definition.


 




Note that:

This line must be injected.

Please correct me if I'm missing something basic. It seems strange that Spring does not automatically inject parent's properties....

5 comments :

  1. You need to define the parent class:


    This way you will inherit all the properties declared for the parent class.

    Bye,
    Luca

    ReplyDelete
  2. the code was deleted...

    bean id="classB" scope="prototype" parent="classA"

    ReplyDelete
  3. Thanks a lot, Luca!
    It works like a charm. But why not the framework figure this out by itself? It will became a maintenance issue when many inheritance got involved. If I change the parent bean name, I need to manually change all the child bean's parent name. Just my 2 cents. Maybe it has to do with performance and other flexibilities...

    ReplyDelete
  4. This way you can configure different parent classes with different behaviours. For example you could easily change from a parent class that provide a real service to a parent that provide a mock service for testing.

    ReplyDelete
  5. Agreed. However, it would be better to have the actual parent inherited by default and use different parent if user specifies 'parent' attribute (override the default value). That way, it simplifies maintenance of the configuration file.

    ReplyDelete