簡體   English   中英

如何使用Google Guice在運行時基於注釋注入接口實現

[英]How to inject an interface implementation based on annotations at runtime using Google Guice

我有以下情況:

public interface ServiceClientAdapter {
    SomeData getSomeData()
}

@LegacyServiceClientAdapter
public class MyLegacyServiceClientAdapterImpl implements ServiceClientAdapter {
    public SomeData getSomeData() {
        // implementation          
    }
}

@NewServiceClientAdapter
public class MyNewServiceClientAdapterImpl implements ServiceClientAdapter  {
    public SomeData getSomeData() {
        // implementation          
    }    
}

public class BusinessLogic {
    @Inject
    private ServiceClientAdapter serviceClientAdapter;
}

LegacyServiceClientAdapter和NewServiceClientAdapter是自定義注釋。

serviceClientAdapter字段的實現將在運行時根據用戶是否已從舊版遷移到新服務來確定。

使用Google Guice完成此依賴項注入的最佳方法是什么?

考慮到將存在不同的BusinessLogic類,每個類都具有自己的(不同的)類似於ServiceClientAdapter的接口以及相應的舊版和新實現類。

理想情況下,這應該使用可在所有用例中使用的一段框架代碼來完成。

我將假設您的LDAP調用的結果可以表示為字符串,例如"legacy""new" 如果沒有,希望您仍然可以改編這個例子。

在您的模塊中,使用MapBinder

public class BusinessLogicModule {
    @Override
    protected void configure() {
        // create empty map binder
        MapBinder<String, ServiceClientAdapter> mapBinder =
                MapBinder.newMapBinder(
                        binder(), String.class, ServiceClientAdapter.class);

        // bind different impls, keyed by descriptive strings
        mapBinder.addBinding("legacy")
                .to(MyLegacyServiceClientAdapterImpl.class);
        mapBinder.addBinding("new")
                .to(MyNewServiceClientAdapterImpl.class);
    }
}

現在,您可以將實例映射(如果需要繼續創建新實例,則可以注入實例提供者的映射)到您的主類中,並使用在運行時發現的字符串來控制獲取哪種類型的實例。

public class BusinessLogic {
    @Inject
    private ServiceClientAdapter serviceClientAdapter;

    @Inject
    private Map<String, ServiceClientAdapter> mapBinder;

    public void setupAndUseClientAdapter() {
        String userType = getUserTypeFromLdapServer();
        serviceClientAdapter = mapBinder.get(userType);
        if (serviceClientAdapter == null) {
            throw new IllegalArgumentException(
                    "No service client adapter available for " +
                    userType + " user type.";
        }
        doStuffWithServiceClientAdapter();
    }
}

暫無
暫無

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

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