2

I want to have a Spring component with prototype scope instantiated as needed at runtime, using pure Java implementation (Spring JavaConfig annotations). Say i have a bean as follows:

@Component
@Scope("prototype")   
public class MyTask {

    @Autowired
    Field myField;

    runTask() {...}
}

I want to be able to do the following:

MyTask task = //instantiate new task
task.runTask();

I can always use:

ApplicationContext.getBean(MyTask.class)

But that would completely contradict the notion of inversion of control. Can this be done with JavaConfig pure Java implementation (i.e. no use of xml files)?

UPDATE:

To be more specific, I'm looking for a way that will be similar to the xml based solution of lookup-method factory that is explained in this SO post

Community
  • 1
  • 1
zuckermanori
  • 1,675
  • 5
  • 22
  • 31

1 Answers1

3

Scope 'prototype' means that each time you call beanFactory.getBean(), you get a fresh instance. And when you inject a dependency (for instance, via @Autowired), Spring (internally) calls that getBean() only once per injection point.

To call it multiple times, you need a BeanFactory, or just call that @Bean-annotated method in your configuration.

An interesting use case of prototype scope with @Configuration is described here: Spring Java Config: how do you create a prototype-scoped @Bean with runtime arguments?

Update

You could implement what you described without the prototype scope.

@Component
public class MyTaskFactoryImpl implements MyTaskFactory {
    @Autowired
    Field myField;

    @Override
    public MyTask newTask() {
        return new MyTask(myField);
    }
}

And in MyTask:

public class MyTask {

    final Field myField;

    public MyTask(Field myField) {
        this.myField = myField;
    }

    public void runTask() {...}
}

Then inject MyTaskFactory taskFactory and use it:

MyTask task = taskFactory.newTask();
task.runTask()
Roman Puchkovskiy
  • 11,415
  • 5
  • 36
  • 72
  • Thanks @rpuch this however make use of Beanfactory.getBean(..) which I prefer not to use. Is this the only way to instantiate a Bean at runtime? – zuckermanori Mar 21 '17 at 14:51
  • @zuckermanori no such a way comes to my mind. But I've updated the answer with an example of how this can be done without using prototype scope (no `BeanFactory` either). – Roman Puchkovskiy Mar 21 '17 at 18:34
  • Thank you @rpuch this is what I had in mind before, still wanted to look for a way to do that. I'll upvote for the creativity, and wait for other answers to come. – zuckermanori Mar 21 '17 at 19:05