2017-10-04 3 views
2

は、私は、このようなクラスを考えてみましょう:何とかプログラムによる豆は私が@Bean注釈付きの豆登録</p> <p>のプログラムと同等であるかを理解したいと思い登録

  1. タイプの豆に依存して、BigDecimal型の 「aDecimal」という名前のBeanの工場として、このメソッドを登録春String
  2. このメソッドは、適切なBeanを というパラメータで呼び出し、結果は "aDecimal" Beanに関連付けられたインスタンスになります。私はこのような何かで同じことをやってみたかった場合

@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); 
    } 
} 

何、この結果を達成するための正しい方法でしょうか?

私はすでにこのことについて少し研究し、私は例えば

How do I create beans programmatically in Spring Boot?

が見つかりましたが、登録のこの種は、私が欲しい、注釈のように強力なようだ、とのは、豆instatiate春することはできません。提供される方法

How to programmatically create bean definition with injected properties?

、これは注入豆パラメータでメソッドを呼び出す機能が欠落していることによってinstatiedするビーン。

私はこれをやりたいのですが、設定ファイルに基づいて、さまざまな修飾子を持つ同じ種類のBeanをたくさん保持する設定クラスがいくつかあります。あなたはIntegrationFlowContextを使用することを検討する必要があり、私は新しい豆と構成を追加する必要があり、構成ファイルが展開さ は今たびに、(これらの多くは春のSessionFactoriesあるとSpringIntegrationはので、私はこれらの事は、春の豆である必要が流れて)

答えて

1

私は問題を解決する方法を見つけました。すべてのことがBeanDefinitionの「段階」でこのように起こります。すべてが春に管理され、注入されたパラメータを持つ@Bean注釈付きメソッドとまったく同じように機能します。注釈付きでプログラムで登録されたBean。ここ

これは面白いです、私は

@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

@Autowired 
private IntegrationFlowContext integrationFlowContext; 

... 


IntegrationFlow myFlow = f -> ...; 

BeanFactoryHandler additionalBean = new BeanFactoryHandler(); 

IntegrationFlowRegistration flowRegistration = 
      this.integrationFlowContext.registration(myFlow) 
        .addBean(additionalBean) 
        .register(); 

これは、IntegrationFlow構造だけでなく、実行時に追加のBeanを登録するフックを提供します。

+0

をやったことで、私はそれを動作させることができるかどうかを確認することでビットを再生します:) とにかく、私もそこに解決策があるはずです考えていましたバネ積分を必要としない –

+0

???あなたは質問に 'spring-integration'とマークされています。だから、私はあなたが 'IntegrationFlowContext'が救助に来る動的な流れに確実に対処することを前提にしました。 Spring FrameworkにはランタイムBean登録のためのクリーンな解決策がないため、Spring Integrationではそのことを打ち出しています。この解決策は 'BeanFactory.registerSingleton()'に基づいています。 Spring Integrationが主な目的でない場合は、ソースコードにいくつかのアイデアを見てみるといいでしょう。 –

+0

私はそれを使用して私は春の統合を追加し、それを使用するソリューションは、私のユースケースは大丈夫ですが、私は依存関係として春の統合を持っていないと私はちょうどと動作するソリューションを見つけることができますそれはさらに良いだろう春 –

関連する問題