有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Guice运行时依赖项参数重新注入

关于Guice的问题。我还在学习,但我能理解基本原理

这个问题在网上已经被问了好几次,但从来没有得到具体的答案(我找不到)

假设我有一个像照片上那样的情况(类似的例子是网络上的一些人)

enter image description here

public class Dog {}

public class Walk implements Walkable {
    private final Dog dog;
    private final boolean leash;

    @Inject
    public Walk(Dog dog, @Assisted boolean leash) {
        this.dog = dog;
        this.leash = leash;
    }

    public void go() {
    }
}

public interface Walkable {
    void go();
}

public interface WalkFactory {
    Walk create(boolean leash);
}

public class AssistedMain {
    public static void main(String[] args) {
        Injector i = Guice.createInjector(new AbstractModule() {
            protected void configure() {

                install(new FactoryModuleBuilder().
                        implement(Walkable.class, Walk.class).
                        build(WalkFactory.class));
            }
        });

        Walk walk = i.getInstance(WalkFactory.class).create(true);
    }
}

太好了。但问题是——我能否以某种方式将该对象实例重新注入到“容器”(注入器)中,以用于依赖该依赖关系的类

所以,让我们添加一个interface Personclass PersonImpl

enter image description here

新课程来源如下:

public interface Person {
    void walkDog();
}

public class PersonImpl implements Person {
    private Walkable walkable;

    @Inject
    public PersonImpl(Walkable walkable) {
        this.walkable = walkable;
    }

    public void setWalkable(Walkable walkable) {
        this.walkable = walkable;
    }

    public void walkDog() {
        walkable.go();
    }
}

所以,问题是——我是否真的能够将这个特定的实例注入到添加的对象中。这是一个简单的例子,但我们可以假设在这个例子下面有10个级别的类

我找到的解决方案不是很灵活。比如:

Injector i = Guice.createInjector(new SimpleModule(false, dog));

然后结合具体实例。这不是很有活力。基本上,每次需要不同的运行时/动态参数时,我都必须重新创建喷油器

Provider<T>很好,FactoryModuleBuilder很有帮助,但是我怎样才能将对象注入到后面呢

这个问题有没有更动态的解决方案

谢谢


共 (3) 个答案

  1. # 1 楼答案

    部分问题取决于你如何解决“false”是你想要为leash field设置的东西。这是来自配置数据还是什么

    提供程序方法可能会有所帮助

    class FooModule extends AbstractModule {
    ...
        @Provides
        Walkable getWalkable(Dog dog) {
            boolean leash = getBooleanFromSomewhere();
            return new Walk(dog, leash);
        }
    }
    

    如果你能澄清布尔值是从哪里来的,这将帮助我理解什么类型的方法是适用的

  2. # 2 楼答案

    MPierce——同意。我会尽力解释我想象问题的方式(如果我错了,你可以纠正我)

    最初源于“服务定位器”模式,认为它可以管理的不仅仅是服务,至少可以说是乐观的

    我们可以将应用程序分为服务和数据类,或者你可以说我们有应用程序和基础架构代码-《依赖注入》,一本很棒的书

    所以,基本上,依赖性注入和依赖性注入框架都是很好的用于解决基础架构或“服务”代码

    任何注入容器/注入器的动态(运行时)参数基本上都会迫使您结束对象图

    例如,我们有以下设计:

    enter image description here

    EmailMessage是一个运行时参数。它可以“注入”到容器/注入器外部的电子邮件服务中,但它会结束对象图如果我们想请求EmailDispatcher,在我们将EmailMessage注入EmailService(我重复一下,这是在injector外部完成的)之后,我们无法再从injector获取EmailDispatcher

    然后,您可以重新设计模型,使其“适合”容器/注入器动态参数的概念

    enter image description here

    但是,你又一次强迫设计,突然,EmailDispatcher承担了太多的责任。它可以用于这样一种环境,在这种环境中,您没有很多基础设施类

    enter image description here

    当您有第三个示例图片中的设计时,您不能使用注入器/容器来获取NextService3实例(也不能低于EmailDispatcher级别)

    问题是-如果你有任何动态(运行时)参数,你只能对需要动态参数的类上面的类使用依赖注入,你可以忽略下面的类

    对吗

  3. # 3 楼答案

    您可以使用custom scopes,就像使用guice servlets一样。这样,您就可以创建实例,然后将其植入注入器