Let's say there is an application that creates an instance of the Task class every time when it needs to process some data. The task instance have some other services injected into it but all this services and the task object itself are unique within a single task instance. Some global services are being injected too of course but they are true application wide singletons. So my question is what is the best way to configure injection of that local (or scoped) singleton instances? I am primarily thinking about using a child context but how to configure it properly is still a question to me. One more thing to mention is that I use annotations and java based configuration.
The solution I finally came up with requires to create a child context. The key point is to specify different child configuration so that parent context is unaware about child component dependencies. The simplest solution is to create a separate java config with enabled component scanning and to place it into a dedicated package.
@Configuration
@ComponentScan
public class TaskConfig {}
public interface TaskFactory {
Task createTask();
}
@Component
public class TaskFactoryImpl implements TaskFactory {
private ApplicationContext parentContext;
@Autowired
public void setParentContext(ApplicationContext parentContext) {
this.parentContext = parentContext;
}
@Override
public Task createTask() {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
context.register(TaskConfig.class);
context.setParent(parentContext);
context.refresh();
return context.getBean(Task.class);
}
}
}