I have a MyTask class which implements Runnable and there can be many such objects instantiated at any given moment. There are certain properties t
Typically adding @Scope("prototype") should not cause null error for autowired blah bean,you should check how you instantiate MyTask bean. I think the problem is that you manually instantiate MyTask like:
MyTask task = new MyTask();
and therefor it goes out of Spring's control that is why its dependency, blah bean, is null , instead of manual instantiation, you need to autowire it and let Spring takes care of its dependencies then blah willnot be null. But then there is another issue. Autowiring a prototype bean, MyTask, whithin another singleton object is wrong. Spring container creates a singleton bean only once, and thus only sets the prototype bean once and this causes the prototype scope not to work.Like below, Myactivity is a singleton which autowires MyTask, I also added a constructor for MyTask to print something once a new instance of MyTask gets created. In below case it only prints once, therefore prototype is not working.
@Component
@Scope("prototype")
public class MyTask implements Runnable {
@Autowired
public SomeSpecialSpringConfiguredConnectionClass blah;
public MyTask(){
System.out.println("New Instance of MyTask");
}
@Override
public void run() {
assert(blah != null);
}
}
@Component
public class MyActivity {
@Autowired
private MyTask task;
public MyTask start() {
return task;
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {MyActivity.class, MyTask.class,
SomeSpecialSpringConfiguredConnectionClass.class})
public class MyTaskTest {
@Autowired
private MyActivity activity;
@Test
public void testActivity() {
for (int i = 0; i < 5; i++) {
MyTask task = activity.start();
task.run();
}
}
}
Based on Spring AOP Scoped proxies I changed @Scope("prototype") to @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "prototype") so the scoped proxy injects a new instance of MyTask every time singleton MyActivity bean gets called.
@Component
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "prototype")
public class MyTask implements Runnable {
@Autowired
public SomeSpecialSpringConfiguredConnectionClass blah;
public MyTask(){
System.out.println("New Instance of MyTask");
}
@Override
public void run() {
assert(blah != null);
}
}
and now the prototype is working fine and this was the result printed in console:
New Instance of MyTask
New Instance of MyTask
New Instance of MyTask
New Instance of MyTask
New Instance of MyTask