2015-09-10 31 views
5

Qual è il modo corretto per passare da un elenco di specifiche di connessione RabbitMQ a una serie di utenti su un canale di registrazione di pubblicazione?Configurazione dinamica con Spring Integration

Vale a dire, dire che ho coniglio config come segue:

rabbits: 
    - hostname: blahblah 
     vhost: blahlbah 
     username: blahlbah 
     password: blahlbalh 
     exchange: blahblah 
    - hostname: blahblah1 
     vhost: blahlbah1 
     username: blahlbah1 
     password: blahlbalh1 
     exchange: blahblah1 
    ... 

ho maresciallo questi in un @NestedConfigurationProperty List<RabbitConfiguration>. Potrei scrivere un metodo @Bean che mi ottiene un AmqpTemplate da uno di quelli List<RabbitConfiguration>, in questo modo:

@Bean 
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public AmqpTemplate amqpTemplate(RabbitConfiguration rabbitConfiguration) { 
    ... 
} 

Posso quindi essenzialmente traccio che a un IntegrationFlow:

@Bean 
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public IntegrationFlow integrationFlow(AmqpTemplate amqpTemplate) { 
    return IntegrationFlows.from(inboundPubSubChannel()).handle(Amqp.outboundAdapter(amqpTemplate)).get(); 
} 

Quello che, invece, è la modo giusto per fare questo per un List<RabbitConfiguration> e il List<IntegrationFlow> risultante gestito da Primavera? Di certo non si tratta solo:

@Bean 
public List<IntegrationFlow> integrationFlows(List<RabbitConfiguration> rabbitConfigurations) { 
    return rabbitConfigurations.stream() 
     .map(this::amqpTemplate) 
     .map(this::integrationFlow) 
     .collect(toList()) 
} 

risposta

0

Penso che quello che stai cercando di fare è di creare dinamicamente bean Spring di tipo IntegrationFlow, sulla base di proprietà di configurazione. Ci sono molte opzioni che hai a seconda di come "magico" o "trasparente" vuoi che sia. Se vuoi la magia completa devi implementare un BeanFactoryPostProcessor e registrarti nel contesto Spring. Qualcosa del genere dovrebbe funzionare:

public class IntegrationFlowPostProcessor implements BeanFactoryPostProcessor{ 

    List<RabbitConfiguration> rabbitConfigurations; 

    public IntegrationFlowPostProcessor(List<RabbitConfiguration> rabbitConfigurations) { 
    this.rabbitConfigurations = rabbitConfigurations; 
    } 

    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
    rabbitConfigurations.stream() 
     .forEach(rabbitConfig -> { 
      IntegrationFlow intFlow = integrationFlow(amqpTemplate(rabbitConfig)); 
      beanFactory.registerSingleton(rabbitConfig.getHostanme(), intFlow); 
     }); 
    } 

    private AmqpTemplate amqpTemplate(RabbitConfiguration rabbitConfiguration) { 
    //Implement here 
    return null; 
    } 

    private IntegrationFlow integrationFlow(AmqpTemplate amqpTemplate) { 
    //Implement here 
    return null; 
    } 
} 

allora si dovrà registrare il post processore nella classe di configurazione:

@Bean public IntegrationFlowPostProcessor ifpp(List<RabbitConfiguration> config { 
    return new IntegrationFlowPostProcessor(config); 
} 

allora si sarebbe in grado di iniettare ogni flusso integrazione da hostname in altri bean utilizzando @Qualifier o come raccolta, diciamo List<IntegrationFlow> con tutti i flussi di integrazione presenti nel contesto Spring.