簡體   English   中英

Spring Boot Starter根據屬性注入bean

[英]spring boot starter inject bean based on property

最近,我正在開發一個彈簧啟動啟動器,為客戶端代碼提供ServiceA 我想提供以下配置屬性:

my.namespace.serviceA=impl1    #or other implemtations

my.namespace.serviceA.impl1.prop1=ServiceAImpl1Prop1Val
my.namespace.serviceA.impl1.prop2=ServiceAImpl1Prop2Val
# some other properties of ServiceA

我還為ServiceA不同實現添加了幾個帶有@ConfigurationProperties批注的Bean類,因為springboot會將這些屬性自動加載到那些Bean中。

我的入門者想為客戶代碼提供ServiceA接口,以便可以將其用作:

@Autowire
private ServiceA serviceA;

我需要給出一個工廠方法,例如:

@Bean
public ServiceA serviceA() {
    //TODO load my.namespace.serviceA and create the corresponding 
    //instance of ServiceA Implementation with given properties
}

由於屬性根據不同的實現而有所不同,是否存在一種優雅的方法來利用@ConfigurationProperties利用屬性bean來實現這種工廠方法?

從外觀上看,您90%都能找到答案。

您可以將ServiceA標記為組件,而不必手動創建Bean,而Spring組件掃描將為您創建Bean。

查看ServiceA的實現

@ConfigurationProperties(prefix = "my.namespace.serviceA.impl1")
@Component
public ConcreteA implements ServiceA {
    private String prop1;
    private String prop2;
}

編輯

基於您想要一個ServiceA實例的事實,您仍然需要使用@ConfigurationProperties注釋類,但要刪除@Component

@ConfigurationProperties(prefix = "my.namespace.serviceA.impl1")
public ConcreteA implements ServiceA {
    private String prop1;
    public void setProp1(String s) {
        prop1 = s;
    }
}

您的財產必須至少有二傳手。

然后在配置類中創建bean

@ConfigurationProperties(prefix = "my.namespace")
@Configuration
public SomeConfig {
    private String serviceA;

    public void setServiceA(String s) {
        serviceA = s;
    }

    @Bean
    public ServiceA serviceA() {
        if (serviceA.equals("ConcreteA1")) {
            return new ConcreteA1();
        } else {
            return new ConcreteA2();
        }
    }
}

使用if語句的方法實際上破壞了開放/封閉的原則,而自省是一種更好的方法,但是我認為您可以理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM