Wednesday, November 19, 2008

[Spring] @Autowired doesn't work in an abstract class

If your @AutoWired doesn't seem to work in an abstract class, it could be because you need to add @Component to the solid class that extends the abstract class.

So if you have an abstract class:
package com.maaloe.test;

import org.springframework.beans.factory.annotation.Autowired;

public abstract class MyAbstractClass {
  @Autowired
  TestService testService;
  public void test() {
    System.out.println("TestService: " + testService.myToString());
  }
}

and a solid class:
package com.maaloe.test;

import org.springframework.stereotype.Component;

@Component
public class MySolidClass extends MyAbstractClass {
  public void mytest() {
    super.test();
  }
}

Note that this abstract class does NOT have a @Component tag, as this is never used as a solid class, so even though it uses @Autowired for injecting its member variables, only the class extending the MyAbstractClass need to have the @Component tag.

I found this rather confusing... but that's apparently the way it works. :)

Heres' the TestService and the TestServiceImpl:
package com.maaloe.services;

public interface TestService {
  String myToString();
}

package com.maaloe.services.impl;

import org.springframework.stereotype.Component;

@Component
public class TestServiceImpl implements TestService {
  public String myToString() {
    return "TestService ping...";
  }
}

and finally, the applicationContext must contain:

<context:component-scan base-package="com.maaloe" />
<context:annotation-config/>


Enjoy...

Note that none of the above have been compiled, it's just written from my memory, so forgive me if it contains minor errors.

Please comment if you have anything to add!