3

您将如何构建下图中显示的对象图?

用户对象必须结合来自两个数据库后端的信息。

同一个对象图的多个配置

4

3 回答 3

3

我找到了使用私有模块的解决方案。

static class Service {
    @Inject Dao daoA;

    public void doSomething() {
        daoA.doA();
    }
}

static class Dao {
    @Inject DataSource dataSource;

    public void doA() {
        dataSource.execute();
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface Connection {}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface X {}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface Y {}

static class DataSource {
    @Connection @Inject String connection;

    public void execute() {
        System.out.println("execute on: " + connection);
    }
}

static class XServiceModule extends PrivateModule {
    @Override
    protected void configure() {
        bind(Service.class).annotatedWith(X.class).to(Service.class);
        expose(Service.class).annotatedWith(X.class);

        bindConstant().annotatedWith(Connection.class).to("http://server1");
    }
}

static class YServiceModule extends PrivateModule {
    @Override
    protected void configure() {
        bind(Service.class).annotatedWith(Y.class).to(Service.class);
        expose(Service.class).annotatedWith(Y.class);

        bindConstant().annotatedWith(Connection.class).to("http://server2");
    }
}

public static void main(String[] args) {
    Injector injector = Guice.createInjector(new XServiceModule(), new YServiceModule()); 

    Service serviceX = injector.getInstance(Key.get(Service.class, X.class));  
    serviceX.doSomething(); 

    Service serviceY = injector.getInstance(Key.get(Service.class, Y.class));
    serviceY.doSomething(); 
}
  • Service 类的不同实例可以通过 X 和 Y 注释来标识。
  • 通过隐藏私有模块中的所有其他依赖项,Dao 和 DataSource 之间没有冲突
  • 在两个私有模块中,可以通过两种不同的方式绑定常量
  • 服务通过暴露暴露。
于 2012-05-14T09:02:45.673 回答
0

我会说您应该使用 Guice 的辅助注入扩展来生成一个工厂,该工厂将 aService应用于 a DataSource,然后将该工厂应用于两个不同Service的 s。

于 2012-05-13T17:42:07.680 回答
0

您可以为此使用 BindingAnnotation 或简单的通用 @Named Annotation。我发现它们与@Provides-Methods 一起使用最简单:

@Provides
@Named("User1")
public SomeUser getUser(Service1 service) {
   return service.getUser();
}
@Provides
@Named("User2")
public SomeUser getUser(Service2 service) {
   return service.getUser();
}

进而:

@Inject
@Named("User1")
private SomeUser someuser;
...
于 2012-05-14T06:09:09.923 回答