Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用GoogleGuice在运行时注入基于注释的接口实现_Java_Dependency Injection_Guice - Fatal编程技术网

Java 如何使用GoogleGuice在运行时注入基于注释的接口实现

Java 如何使用GoogleGuice在运行时注入基于注释的接口实现,java,dependency-injection,guice,Java,Dependency Injection,Guice,我有以下情况: public interface ServiceClientAdapter { SomeData getSomeData() } @LegacyServiceClientAdapter public class MyLegacyServiceClientAdapterImpl implements ServiceClientAdapter { public SomeData getSomeData() { // implementation

我有以下情况:

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字段的实现将在运行时由用户是否已从旧服务迁移到新服务来确定

使用GoogleGuice实现依赖注入的最佳方法是什么

考虑到将存在不同的BusinessLogic类,每个类都有自己的(不同的)ServiceClientAdapter类接口以及相应的旧实现类和新实现类


理想情况下,这应该通过一段可以在所有用例中使用的框架代码来完成。

我假设LDAP调用的结果可以表示为字符串,比如说
“legacy”
“new”
。如果没有,希望您仍然能够适应此示例

在您的模块中,使用:

公共类BusinessLogicModule{
@凌驾
受保护的void configure(){
//创建空地图活页夹
MapBinder MapBinder=
MapBinder.newMapBinder(
binder()、String.class、ServiceClientAdapter.class);
//绑定不同的impl,由描述性字符串键入
mapBinder.addBinding(“遗留”)
.to(MyLegacyServiceClientAdapterImpl.class);
mapBinder.addBinding(“新”)
.to(MyNewsServiceClientAdapterImpl.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();
    }
}
公共类业务逻辑{
@注入
私人服务客户端适配器服务客户端适配器;
@注入
私人地图装订机;
公共无效设置和使用客户端适配器(){
字符串userType=getUserTypeFromLdapServer();
serviceClientAdapter=mapBinder.get(用户类型);
如果(serviceClientAdapter==null){
抛出新的IllegalArgumentException(
“没有可用于的服务客户端适配器”+
用户类型+“用户类型。”;
}
doStuffWithServiceClientAdapter();
}
}

如何确定用户是否已迁移?是否检查了系统属性或其他内容?将通过调用LDAP服务器(稍后将缓存)来确定。正在以泛型方式实现此功能,但出现以下错误:java.util.Map不能用作键;它未完全指定。我是否应确保所有ServiceClientAdapter都实现根接口?或者是否有某种方法使用TypeLiteral来允许泛型?以及如何使用提供程序类而不是是否包含对LDAP服务器的调用?@rudolfv如果没有看到您的代码,我无法猜测映射错误来自何处,尤其是因为我不确定您为什么试图使用Impl类作为映射的键。@rudolfv映射绑定器不包含对LDAP服务器的调用,它包含一个基于结果的决策映射如果你想在你的类中使用impl提供程序,只需
@injectmap mapBinder
而不是我上面所说的,然后调用
mapBinder.get(userType).get()
而是获得一个干净的实例。不需要对模块进行任何更改。关键是AdapterImplType,它是一个枚举。但我同意,在没有看到代码的情况下,您很难伸出援手。我成功地获得了一个运行的解决方案,只有一个提供程序,没有MapBinder。原因是我正在运行Weblogic 10.3.6 EJB(J2EE 5),这迫使我以某种方式引导GUI。我还有一个限制,我希望LDAP查找代码位于中心位置,而不是BusinessLogic EJB的实现者甚至应该知道的东西。如果您想看看,我可以创建Git repo?
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();
    }
}