動態

2016-08-19 12 views
0

創建各種豆類的當前項目我想有以下能力:動態

「對於任何擴展接口接口X,通過這個靜態工廠方法創建一個bean,使用另一個(自動裝配)豆。」

找到擴展X的所有接口都沒問題,反射效果很好。但我還沒有找到任何方法將自己注入Spring生命週期,以便Spring知道這些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之後纔可用,這就導致需要確定@DependsOn("dynamicBeanFactory")

那麼,有沒有更好的方法在生命週期中注入一個Bean(定義),以便某些工廠類用於創建許多bean(定義),並且能夠在那裏使用@Autowired

回答

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的兩個參數"someString"classclz在豆myFactoryBean上調用方法myFactoryMethod