2017-10-04 1 views
2

ich möchte verstehen, was ist die programmatische Äquivalent einer @Bean kommentierten Bohnen RegistrierungProgrammatische Bean Registrierung

Können sagen, ich habe eine Klasse wie folgt:

@Configuration 
public class SimpleConfiguration { 
    @Bean 
    public BigDecimal aDecimal(String example) { 
     return new BigDecimal(example); 
    } 
} 

hier ist das, was ich denke, geschieht hier :

  1. Frühling irgendwie für eine Bean mit dem Namen „aDecimal“ vom Typ BigDecimal mit einer Abhängigkeit von einer Bean vom Typdiese Methode als Fabrik registrierenString
  2. irgendwann wird diese Methode mit der richtigen Bean als Parameter aufgerufen und das Ergebnis wird die Instanz sein, die der "aDecimal" -Bohne zugeordnet ist.

Wenn ich das gleiche mit so etwas wie dies tun wollte:

@Configuration 
public class DynamicConfiguration { 

    public void registerDefinition() { 
     /* i know it can't be like this but i hope it's clear what i mean */ 
     register("aDecimal", (example) -> aDecimal(example)); 
    } 

    public BigDecimal aDecimal(String example) { 
     /* this could be any kind of complex bean creation method */ 
     return new BigDecimal(example); 
    } 
} 

was wäre der richtige Weg, um dieses Ergebnis zu erreichen?

i erforschen schon ein wenig über das, und ich fand zum Beispiel

How do I create beans programmatically in Spring Boot?

aber diese Art der Registrierung so stark nicht wie die Anmerkung erscheinen, und lassen Sie sich Feder instatiate die Bohne, ich will der Bohne bis durch eine Methode bereitgestellt

How to programmatically create bean definition with injected properties?

und dies fehlt die Fähigkeit, eine Methode aufzurufen mit eingespritztem bean Parameter instatied werden.

Der Grund, warum ich dies tun möchte, ist, dass ich einige Konfigurationsklassen habe, die eine Menge der gleichen Art von Beans mit unterschiedlichen Qualifiern enthalten, basierend auf einer Konfigurationsdatei. jetzt jedes Mal, wenn die Konfigurationsdatei erweitert, ich brauche neue Bohnen und Konfigurationen hinzufügen (viele davon sind Feder SessionFactories und SpringIntegration fließt so muss ich diese Dinge Frühling Bohnen sein)

Antwort

1

Ich habe den Weg gefunden, um mein Problem zu lösen, es passiert alles in der BeanDefinition "Phase" auf diese Weise wird alles von Feder verwaltet und funktioniert genau so wie eine @Bean annotierte Methode mit injizierten Parametern, es auch sauber Brücke zwischen Kommentierte und programmatisch registrierte Beans.

hier ist, was ich

@Configuration 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = { TestSpringDynamicConfiguration.class }) 
public class TestSpringDynamicConfiguration implements BeanDefinitionRegistryPostProcessor { 

    @Autowired 
    @Qualifier("qualified") 
    private String dynamicString; 

    @Bean 
    public Integer zero() { 
     return 0; 
    } 

    public String zeroString(Integer aInteger) { 
     return aInteger.toString(); 
    } 

    @Override 
    public void postProcessBeanDefinitionRegistry(final BeanDefinitionRegistry registry) throws BeansException { 
     GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); 
     beanDefinition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_CONSTRUCTOR); 
     beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); 

     beanDefinition.setFactoryBeanName("testSpringDynamicConfiguration"); 
     beanDefinition.setFactoryMethodName("zeroString"); 

     registry.registerBeanDefinition("qualified", beanDefinition); 
    } 

    @Override public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException { } 

    @Test 
    public void testDynamicConfiguration() throws Exception { 
     assertThat(dynamicString, is("0")); 
    } 
} 
2

Sie müssen berücksichtigen IntegrationFlowContext verwenden:

Es bietet für Sie Hooks zur Registrierung zusätzliche Beans zur Laufzeit, nicht nur IntegrationFlow Struktur.

+0

tat Das ist interessant, ich mit ihm ein bisschen spielen werde, um zu sehen, ob ich es funktionieren :) Auf jeden Fall machen kann ich dachte, es auch gibt eine Lösung sein sollte das erfordert keine Frühlingsintegration –

+0

??? Ihre Frage ist mit "Federintegration" gekennzeichnet, und Sie erwähnen Integrationsflüsse in Ihrer Frage.Also habe ich angenommen, dass Sie sich definitiv mit dynamischen Flows beschäftigen, wobei 'IntegrationFlowContext' zur Rettung kommt. Das Spring Framework hat keine saubere Lösung für die Laufzeit-Bean-Registrierung, daher entschließen wir uns in Spring Integration dazu, es zu versuchen. Die Lösung basiert jedoch auf dem 'BeanFactory.registerSingleton()'. Ich denke, Sie können für einige Ideen in den Quellcode schauen, wenn Spring Integration nicht Ihr Hauptziel ist. –

+0

ich habe spring-integration hinzugefügt, weil ich es benutze, und lösungen, die es verwenden, sind ok für meinen einsatzfall, aber ich habe andere projekte, die keine federintegration als abhängigkeit haben und wenn ich eine lösung finde, die einfach funktioniert Frühling, das wäre noch besser –

Verwandte Themen