如何将接受 Class<T> 并生成 T 的工厂方法集成到 Spring
How to integrate a factory method which accepts Class<T> and produces T into Spring
我有一个实现如下内容的工厂对象:
public interface MyFactory {
<T> T getInstance(Class<T> clazz);
}
可以这样使用:
MyService s = factory.getInstance(MyService.class);
它可以在clazz
的基础上生成多种实例。如果它得到一个工厂对象不支持的 clazz
,它 returns null.
现在我正在编写一个 Spring 应用程序 (Spring Boot 2.0.1) 并希望将其注入机制与工厂对象一起使用。例如,我想做这样的事情:
@Controller
public class MyController {
@Autowired
private MyService s;
}
有没有办法像这样把MyFactory对象集成到Spring中?我知道我可以为每个 class 手动创建绑定,但我正在寻找更简单的方法。
我添加了以下方法,returns 一组 class 工厂对象支持:
Set<Class<?>> getSupportedClasses();
然后我将以下 class 放入我的 Spring 应用程序中,它似乎工作正常:
@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)));
}
}
我有一个实现如下内容的工厂对象:
public interface MyFactory {
<T> T getInstance(Class<T> clazz);
}
可以这样使用:
MyService s = factory.getInstance(MyService.class);
它可以在clazz
的基础上生成多种实例。如果它得到一个工厂对象不支持的 clazz
,它 returns null.
现在我正在编写一个 Spring 应用程序 (Spring Boot 2.0.1) 并希望将其注入机制与工厂对象一起使用。例如,我想做这样的事情:
@Controller
public class MyController {
@Autowired
private MyService s;
}
有没有办法像这样把MyFactory对象集成到Spring中?我知道我可以为每个 class 手动创建绑定,但我正在寻找更简单的方法。
我添加了以下方法,returns 一组 class 工厂对象支持:
Set<Class<?>> getSupportedClasses();
然后我将以下 class 放入我的 Spring 应用程序中,它似乎工作正常:
@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)));
}
}