I have a factory object which implements something like the following:
public interface MyFactory {
<T> T getInstance(Class<T> clazz);
}
It can be used like this:
MyService s = factory.getInstance(MyService.class);
It can produce many kinds of instances based on clazz
. If it gets a clazz
which is not supported by the factory object, it returns null.
Now I'm writing a Spring application (Spring Boot 2.0.1) and want to use its injection mechanism with the factory object. For example, I want to do something like this:
@Controller
public class MyController {
@Autowired
private MyService s;
}
Is there any way to integrate the MyFactory object into Spring like this? I know I can create bindings for each class manually but I'm looking for an easier way.
I added the following method which returns a set of classes the factory object supports:
Set<Class<?>> getSupportedClasses();
Then I put the following class into my Spring app and it seems to be working fine:
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class SomeBean {
private static final Logger log = LoggerFactory.getLogger(SomeBean.class);
private final MyFactory factory;
private final GenericApplicationContext context;
@Autowired
public SomeBean(GenericApplicationContext context, MyFactory factory) {
this.context = context;
this.factory = factory;
}
@PostConstruct
public void init() {
factory.getSupportedClasses().forEach(this::register);
}
private <T> void register(Class<T> clazz) {
log.info("Registering {} as a bean into ApplicationContext", clazz);
context.registerBean(clazz,
() -> factory.getInstance(clazz),
(beanDefinition -> beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)));
}
}