ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java – 为什么Guice不能绑定中间依赖?

2019-08-29 20:01:12  阅读:171  来源: 互联网

标签:java dependency-injection guice


这是我的代码:

// Groovy
interface MyMapper {
    Buzz toBuzz(Fizz fizz);
}

class MyMapperImpl implements MyMapper {
    @Named("SIMPLE_FOOBAR")
    Foobar foobar;

    MyMapperImpl(Foobar foobar) {
        super();
        this.foobar = foobar;
    }

    @Override
    Buzz toBuzz(Fizz fizz) {
        // ...etc.
    }
}

class Whistlefeather {
    MyMapper mapper;

    Whistlefeather(MyMapper mapper) {
        super();

        this.mapper = mapper;
    }

    void doSomething(Fink fink) {
        Fizz fizz = getSomehow(fink);
        Buzz buzz = mapper.toBuzz(fizz);

        // Do something with 'buzz'...
    }
}

class ApplicationMain {
    Whistlefeather whistlefeather;

    @Inject
    ApplicationMain(Whistlefeather whistlefeather) {
        super();

        this.whistlefeather = whistlefeather;
    }

    static void main(String[] args) {
        Injector injector = Guice.createInjector(new ApplicationModule());
        ApplicationMain appMain = injector.getInstance(ApplicationMain);
        appMain.run();
    }

    void run() {
        whistlefeather.doSomething(new Fink());
    }
}

这是我的Guice模块:

class ApplicationModule extends AbstractModule {
    @Override
    protected void configure() {
        // I have to name the Foobars because in reality there will be
        // *many* of them, each configured slightly different.
        bind(Foobar.class).annotatedWith(Names.named("SIMPLE_FOOBAR"))
            .toInstance(new Foobar(true, true, false, 103, "yee haw"));

        bind(MyMapper.class).to(MyMapperImpl);
    }
}

这是我的例外:

Could not find a suitable constructor in com.me.myapp.MyMapperImpl.
Classes must have either one (and only one) constructor annotated
with @Inject or a zero-argument constructor that is not private.

我的理解是,如果我通过Injector#getInstance(…)方法直接调用它们,我只需要用@Inject注释构造函数.由于我使用ApplicationMain执行此操作,其中包含对Whistlefeather的引用,其中包含对MyMapper的引用,因此我不认为我必须注释MyMapperImpl构造函数.

关于我在哪里出错的任何想法?

解决方法:

为了让Guice创建任何对象,它必须知道要使用哪个构造函数.这在Object Graph下一直都是如此.

请考虑以下代码:

public interface Something { }
public class SomethingImpl implements Something {
  private final String data;

  public SomethingImpl(String data) {
    this.data = data;
  }

  public SomethingImpl(Integer data) {
    this.data = data.toString();
  }
}
public class AnotherClass {
  private final Something something;

  @Inject
  public AnotherClass(Something something) {
    this.something = something;
  }
}
public class MyModule extends AbstractModule {
  @Override
  protected void configure() { 
    bind(Something.class).to(SomethingImpl.class);
    bind(String.class).toInstance("Hello!");
    bind(Integer.class).toInstance(50);
  }
}

在这种情况下,Guice如何知道在SomethingImpl中使用哪个构造函数?如果你是Guice的作者,你会怎么写呢?

显然,你无法回答,因为这是不可能的.必须有某种机制告诉Guice使用哪个构造函数,无论它是否由Injector.getInstance()调用;这就是为什么你必须注释至少一个构造函数.如果指定了一个,Guice将默认使用无参数构造函数,但如果没有,则Guice不知道该怎么做.

标签:java,dependency-injection,guice
来源: https://codeday.me/bug/20190829/1763190.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有