gpt4 book ai didi

从属性文件创建 Spring Boot 动态 Bean

转载 作者:行者123 更新时间:2023-12-03 22:55:36 24 4
gpt4 key购买 nike

如何根据application.yml文件动态定义bean?

例如,YAML 文件如下所示:

service:
host: http://localhost:8080/
account:
url: /account
content-type: application/json
registry:
url: /registry
content-type: application/xml

这将动态创建两个 HttpHeadersContent-Type header 集。

这是我现在定义 bean 的方式:
@Bean
public HttpHeaders accountHeaders(
@Value("${service.account.content-type}") String contentType
) {
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.CONTENT_TYPE, contentType);
return headers;
}

@Bean
public HttpHeaders registryHeaders(
@Value("${service.registry.content-type}") String contentType
) {
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.CONTENT_TYPE, contentType);
return headers;
}

如果我需要添加更多端点,我需要复制和粘贴这些 bean,我想避免这种情况。

注意:这些动态 bean 不需要任何其他 bean。我不确定这是否有所作为。它只需要加载配置。

最佳答案

有几个选项:

  • 使用程序化(“功能性”)bean 注册。通过这种方式,注册 bean 是一个函数,您可以使用 for 循环和 if/else 等。 Aliaksei 的示例演示了这一点,有点。我通常使用 ApplicationContextInitializerSpringApplicationBuilder() 注册(而不是 SpringApplication.run(..) )。
  • 你可以使用 ImportBeanDefinitionRegistrar .实现它,然后使用 BeanDefinitions 注册 bean .使用 @Import(MyIbdr.class) 导入该类.

  • package com.example.dynabeans;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanDefinitionHolder;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.*;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.stereotype.Component;

    import java.util.UUID;

    @SpringBootApplication
    public class DynabeansApplication {

    public static void main(String[] args) {
    SpringApplication.run(DynabeansApplication.class, args);
    }

    }

    class Foo {

    private final String id = UUID.randomUUID().toString();

    @Override
    public String toString() {
    return "Foo{" + id + "}";
    }
    }


    @Component
    class FooListener {

    private final Log log = LogFactory.getLog(getClass());

    FooListener(Foo[] foos) {
    log.info("there are " + foos.length + " " + Foo.class.getName() + " instances.");
    }

    }

    @Component
    class LoopyBeanRegistrar implements BeanDefinitionRegistryPostProcessor {

    private final Log log = LogFactory.getLog(getClass());
    private final int max = (int) (Math.random() * 100);

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    log.info("registering " + max + " beans.");
    for (int i = 0; i < max; i++) {
    BeanDefinitionBuilder gdb = BeanDefinitionBuilder.genericBeanDefinition(Foo.class, () -> new Foo());
    AbstractBeanDefinition abd = gdb.getBeanDefinition();
    BeanDefinitionHolder holder = new BeanDefinitionHolder(abd, Foo.class.getName() + '#' + i, new String[0]);
    BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
    }
    }

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

    }
    }

    关于从属性文件创建 Spring Boot 动态 Bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48161636/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com