首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >程序化Bean注册

程序化Bean注册
EN

Stack Overflow用户
提问于 2017-10-04 15:57:22
回答 2查看 1.5K关注 0票数 2

我想了解@Bean注释的bean注册的编程等效性是什么

假设我有这样一门课:

代码语言:javascript
复制
@Configuration
public class SimpleConfiguration {
    @Bean
    public BigDecimal aDecimal( String example ) {
        return new BigDecimal( example );
    }
}

我认为这里发生的事情如下:

  1. 不知怎么,spring将此方法注册为BigDecimal类型的名为“BigDecimal”的bean的工厂,并依赖于类型为String的bean。
  2. 在某个时候,将以正确的bean作为参数调用该方法,结果将是与"aDecimal“bean相关联的实例。

如果我也想这样做的话:

代码语言:javascript
复制
@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?

但是这种注册似乎没有注释那么强大,让我们让spring将bean实例化,我希望通过提供的方法来安装bean

How to programmatically create bean definition with injected properties?

这就缺少了调用带有注入bean参数的方法的能力。

我之所以要这样做,是因为我有一些配置类,这些类基于配置文件,包含许多具有不同限定符的相同类型的bean。现在,每当配置文件展开时,我都需要添加新的bean和配置(其中许多是spring SessionFactories和SpringIntegration流,所以我需要这些东西是spring )。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-04 22:49:50

我找到了解决问题的方法,这一切都发生在BeanDefinition“阶段”--这种方式--所有的东西都由spring来管理--与带有注入参数的@Bean注释方法完全一样,它还在带注释的Bean和以编程方式注册的Bean之间建立了清晰的桥梁。

以下是我所做的

代码语言:javascript
复制
@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
EN

Stack Overflow用户

发布于 2017-10-04 16:54:40

您需要考虑使用IntegrationFlowContext

代码语言:javascript
复制
@Autowired
private IntegrationFlowContext integrationFlowContext;

...


IntegrationFlow myFlow = f -> ...;

BeanFactoryHandler additionalBean = new BeanFactoryHandler();

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

它提供了钩子在运行时注册其他bean,而不仅仅是IntegrationFlow结构。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46569255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档