Java 如何将Guice辅助注入用于此工厂模式?

Java 如何将Guice辅助注入用于此工厂模式?,java,guice,Java,Guice,下面是我编写的工厂模式。但是,为了把它变成一个提供者,Guice并没有起到很大的作用 class ClientA extends AbstractClient {...} 请提供一些建议,说明如何使用Guice AssistedInject以提供程序格式编写此文件。是否尝试手动编写工厂?您链接的手册有一个很好的示例,您的代码将很容易翻译成Guice public interface ClientFactory { AbstractClient create(String key); }

下面是我编写的工厂模式。但是,为了把它变成一个提供者,Guice并没有起到很大的作用

class ClientA extends AbstractClient {...}

请提供一些建议,说明如何使用Guice AssistedInject以提供程序格式编写此文件。

是否尝试手动编写工厂?您链接的手册有一个很好的示例,您的代码将很容易翻译成Guice

public interface ClientFactory {
    AbstractClient create(String key);
}

public class ClientFactoryImpl implements ClientFactory {
    @Override
    public AbstractClient create(String key) {
        if ("A".equals(key)) {
            return new ClientA();
        } else {
            return new ClientB();
        }
    }
}
并将工厂与植入相结合

bind(ClientFactory.class).to(ClientFactoryImpl.class);

在你的情况下,援助项目是有害的。它提供的只是自动构建ClientFactoryImpl。实现只将注入的和辅助的参数传递给构造函数。但是在create方法中有一些非常重要的逻辑。在这种情况下,我建议您自己创建工厂实现。

首先,我绝对同意@Lesiak。代码
client=newclientb.Builder()…build()不清楚,因为省略号可以是您在客户端A/B上设置的任意数量的字段

但是,为了给您一个如何在特定实例中使用AssistedInject的示例:

class ClientA extends AbstractClient {
    @Inject
    public ClientA(ServiceOne serviceOne,
            ServiceTwo serviceTwo,
            @Assisted MyObject myObject) {
        ...
    }
}

class ClientB extends AbstractClient {
    // Same constructor as ClientA
}
然后,您的工厂将看起来像:

interface ClientFactory {
    @Named("ClientA") public AbstractClient getClientA(...);
    @Named("ClientB") public AbstractClient getClientB(...);
} 
您的参数可以是不同的对象,也可以是您想要的任何对象,但它们本质上必须与构造函数@Assisted注释匹配。现在你可以明白为什么@Lesiak提供了他的答案,如果你的构建器在ClientA上设置了10个字段,那么你的工厂方法将需要10个方法参数,而且非常难以控制

然后,您可以将其用于:

@Inject ClientFactory clientFactory;

...
AbstractClient client = clientFactory.getClientA(something, something1, ...);
...

假设您希望直接创建对象,因此需要使用@Assisted,那么可以让Guice创建命名工厂:

import javax.inject.Inject;

// com.google.inject:guice:4.2.2
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
// com.google.inject.extensions:guice-assistedinject:4.2.2
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryModuleBuilder;

public class StackOverflow {
    public static void main(String[] args) {
        final Injector injector = Guice.createInjector(new GuiceModule());
        Key<ClientFactory> key = Key.get(ClientFactory.class, Names.named(args[0]));
        System.out.println("Client: " +  injector.getInstance(key).create("xxx"));
    }
}

class GuiceModule extends AbstractModule {
    @Override
    protected void configure() {
        install(new FactoryModuleBuilder().implement(AbstractClient.class, ClientA.class)
            .build(Key.get(ClientFactory.class, Names.named("ClientA"))));
        install(new FactoryModuleBuilder().implement(AbstractClient.class, ClientB.class)
            .build(Key.get(ClientFactory.class, Names.named("ClientB"))));
    }
}

abstract class AbstractClient {
}

class ClientA extends AbstractClient {
    private String key;
    @Inject
    public ClientA(@Assisted String key) {
        this.key = key;
    }
    @Override
    public String toString() {
        return "ClientA [key=" + key + "]";
    }
}

class ClientB extends AbstractClient {
    private String key;
    private Injector injector; // just an example for additional injections
    @Inject
    public ClientB(@Assisted String key, Injector injector) {
        this.key = key;
        this.injector = injector;
    }
    @Override
    public String toString() {
        return "ClientB [key=" + key + "]";
    }
}

interface ClientFactory {
    AbstractClient create(String key);
}
import javax.inject.inject;
//注入:guice:4.2.2
导入com.google.inject.AbstractModule;
导入com.google.inject.Guice;
导入com.google.inject.Injector;
导入com.google.inject.Key;
导入com.google.inject.name.Names;
//扩展:guice assistedinject:4.2.2
导入com.google.inject.assistedinject.Assisted;
导入com.google.inject.assistedinject.FactoryModuleBuilder;
公共类堆栈溢出{
公共静态void main(字符串[]args){
final Injector=Guice.createInjector(新的GuiceModule());
Key=Key.get(ClientFactory.class,Names.named(args[0]);
System.out.println(“客户端:”+injector.getInstance(key.create)(“xxx”);
}
}
类GuiceModule扩展了AbstractModule{
@凌驾
受保护的void configure(){
安装(新FactoryModuleBuilder().implement(AbstractClient.class,ClientA.class)
.build(Key.get(ClientFactory.class,Names.named)(“ClientA”));
安装(新FactoryModuleBuilder().implement(AbstractClient.class,ClientB.class)
.build(Key.get(ClientFactory.class,Names.named(“ClientB”)));
}
}
抽象类AbstractClient{
}
类ClientA扩展了AbstractClient{
私钥;
@注入
公共客户端(@Assisted String key){
this.key=key;
}
@凌驾
公共字符串toString(){
返回“ClientA[key=“+key+”]”;
}
}
类ClientB扩展了AbstractClient{
私钥;
私有注入器;//只是额外注入器的一个示例
@注入
公共客户端B(@辅助字符串键,注入器){
this.key=key;
这个喷油器=喷油器;
}
@凌驾
公共字符串toString(){
返回“ClientB[key=“+key+”]”;
}
}
接口客户端工厂{
抽象客户端创建(字符串键);
}

这种方法的缺点是,为了使用动态输入,您需要一个对注入器的引用,Guice抱怨这非常慢-这对您来说可能不是一个问题。如果有人知道如何用更好的方法替换direct injector.getInstance调用,请告诉我

典型的机器人腿示例(一条左腿,一条右腿)可能与此重复。你根本不需要辅助注射。是我写的。但是,我是Guice的新手,我被要求更改我在本文中编写的工厂模式。所以,如果可能的话,请解释一下。提前谢谢。
interface ClientFactory {
    @Named("ClientA") public AbstractClient getClientA(...);
    @Named("ClientB") public AbstractClient getClientB(...);
} 
@Inject ClientFactory clientFactory;

...
AbstractClient client = clientFactory.getClientA(something, something1, ...);
...
import javax.inject.Inject;

// com.google.inject:guice:4.2.2
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
// com.google.inject.extensions:guice-assistedinject:4.2.2
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryModuleBuilder;

public class StackOverflow {
    public static void main(String[] args) {
        final Injector injector = Guice.createInjector(new GuiceModule());
        Key<ClientFactory> key = Key.get(ClientFactory.class, Names.named(args[0]));
        System.out.println("Client: " +  injector.getInstance(key).create("xxx"));
    }
}

class GuiceModule extends AbstractModule {
    @Override
    protected void configure() {
        install(new FactoryModuleBuilder().implement(AbstractClient.class, ClientA.class)
            .build(Key.get(ClientFactory.class, Names.named("ClientA"))));
        install(new FactoryModuleBuilder().implement(AbstractClient.class, ClientB.class)
            .build(Key.get(ClientFactory.class, Names.named("ClientB"))));
    }
}

abstract class AbstractClient {
}

class ClientA extends AbstractClient {
    private String key;
    @Inject
    public ClientA(@Assisted String key) {
        this.key = key;
    }
    @Override
    public String toString() {
        return "ClientA [key=" + key + "]";
    }
}

class ClientB extends AbstractClient {
    private String key;
    private Injector injector; // just an example for additional injections
    @Inject
    public ClientB(@Assisted String key, Injector injector) {
        this.key = key;
        this.injector = injector;
    }
    @Override
    public String toString() {
        return "ClientB [key=" + key + "]";
    }
}

interface ClientFactory {
    AbstractClient create(String key);
}