对于当前项目,我希望具备以下功能:
“对于扩展接口X的任何接口,使用另一个(自动装配的)bean通过此静态工厂方法创建一个bean。”
查找扩展X的所有接口都没有问题,反射做得非常好。但我还没有找到任何方法将自己注入Spring生命周期,以便Springs知道这些bean可以存在。
目前,我正在尝试使用简单的bean ...
@Component
public class DynamicBeanFactory {
@Autowired
private Service myService;
@Autowired
private ConfigurableListableBeanFactory beanFactory;
protected List<Class<? extends X>> findAllSubclasses() { ... }
@PostConstruct
public void createOneBeanPerClass() {
... create beans from findAllSubclasses(), using myService
beanFactory.registerSingleton(name, bean);
}
}
显然这会导致问题,例如......
@Autowired
private YextendingX dependency;
...不会一直有效,因为Spring无法知道YextendingX
只有在创建DynamicBeanFactory
后才可用,这导致需要{ {1}},只是为了确定。
那么,有没有更好的方法将Bean(定义)注入生命周期,因此一些工厂类用于创建许多bean(定义),并且能够在那里使用@DependsOn("dynamicBeanFactory")
。
答案 0 :(得分:0)
在玩了一会儿后,以下解决方案似乎可以解决问题......
@Component
public class DynamicBeanRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
List<Class<? extends X> classes = findAllSubclasses(); // implemented via Reflections
for (Class<? extends X> clz : classes) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(clz);
beanDefinition.setTargetType(clz);
beanDefinition.setFactoryBeanName("myFactoryBean");
beanDefinition.setFactoryMethodName("myFactoryMethod");
ConstructorArgumentValues properties = new ConstructorArgumentValues();
properties.addGenericArgumentValue("someString");
properties.addGenericArgumentValue(clz);
beanDefinition.setConstructorArgumentValues(properties);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
registry.registerBeanDefinition(entry.getKey(), beanDefinition );
}
}
etc.
这样,所有bean似乎都找到并添加为bean定义,因此可以正确地确定它们的创建顺序。为了创建它们,使用所需bean的两个参数myFactoryMethod
和myFactoryBean
"someString"
在bean class
上调用方法clz
。