tenticon
tenticon

Reputation: 2913

spring - autowiring interface in abstract class with scope prototype does not work

I have an example spring project where I have an abstract class Athlete into which I want to autowire an interface Trainer.

The Athlete is Runnable and implementations thereof override a perform() method.

When I call perform() in Sprinter (extends Athlete) the Trainer instance that I wanted to autowire into Athlete is still null

Athlete:

@Component
@Scope("prototype")
public abstract class Athlete implements Runnable{

    protected final String name;

    @Autowired protected Trainer trainer;


    public Athlete(String name)
    {
        this.name = name;
    }

    protected abstract void perform();

    @Override
    public void run() {
        perform();
    }
}

Sprinter:

@Component
@Scope("prototype")
public class Sprinter extends Athlete {

    public Sprinter(String name) {
        super(name);
    }

    @Override
    protected void perform() 
    {
        this.trainer.giveAdviceTo(name); // TRAINER IS NULL !!!!!!
        for(int i=0;i<3;i++)
        {
            System.out.println("Sprinting...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

Implementation of Trainer

@Component
public class TrainerImpl implements Trainer{

    @Override
    public void giveAdviceTo(String name)
    {
        System.out.println("Go " + name + "!!");
    }
}

Thanks for the help

Upvotes: 0

Views: 1505

Answers (2)

Maarten
Maarten

Reputation: 196

Looks to me that in your main class, you are creating these objects yourself.

Athlete a1 = new Sprinter("adam");

Spring can only autowire objects into (managed) beans. At this point, Spring simply does not know that the instance of Sprinter that you've created even exists.

When you let Spring create the bean for you, it will also inject all @Autowired dependencies.

@Autowired
private BeanFactory beanFactory;


@Override
public void run(String... args) throws Exception {
    Sprinter adam = beanFactory.getBean(Sprinter.class, "adam");
    TennisPlayer roger = beanFactory.getBean(TennisPlayer.class, "roger");

    executor.execute(adam);
    executor.execute(roger);
}

Upvotes: 1

Vicky
Vicky

Reputation: 1225

You are trying to create your bean object with the non-default constructor (constructor with arguments). Either you can declare default constructor in your class or if you really want to create bean instances with non-default constructor then you can do something like this.

https://dzone.com/articles/instanciating-spring-component

Upvotes: 1

Related Questions