【问题标题】:Is it possible and how to do Assisted Injection in Spring?是否有可能以及如何在春季进行辅助注射?
【发布时间】:2011-09-07 12:35:54
【问题描述】:

在 Guice 2 或 3 中,存在所谓的 Assisted/Partial Inject 描述 here. 有了这个,Guice 为我的对象合成工厂实现(实现我的接口),并且一些构造函数参数由 Guice 注入,还有一些是提供的从上下文。

是否有可能以及如何使用 Spring 做同样的事情?

【问题讨论】:

  • 这个问题已经相当老了。春天有什么变化吗?这听起来像是一个合理的功能请求(不是吗?)
  • 嗨 Op De Cirkel,很抱歉让您的线程死灵,但我最终可能会解决您的问题,并在新答案中链接:) cc @theadam

标签: java spring dependency-injection


【解决方案1】:

以下内容完全符合我的要求。虽然,它没有综合工厂的实现,但它已经足够好了,因为工厂可以访问 injection context 以便在期间可以使用其他 beans(可注入的工件)建造。它使用基于 java 的 @Configuration 而不是 XML,但它也适用于 XML。

工厂界面:

public interface Robot {

}

// Implementation of this is to be injected by the IoC in the Robot instances
public interface Brain {
    String think();
}

public class RobotImpl implements Robot {

    private final String name_;
    private final Brain brain_;

    @Inject
    public RobotImpl(String name, Brain brain) {
        name_ = name;
        brain_ = brain;
    }

    public String toString() {
        return "RobotImpl [name_=" + name_ + "] thinks about " + brain_.think();
    }
}

public class RobotBrain implements Brain {
    public String think() {
        return "an idea";
    }
}


// The assisted factory type
public interface RobotFactory {
    Robot newRobot(String name);
}

// 这是显示如何进行辅助注入的 Spring 配置

@Configuration
class RobotConfig {

    @Bean @Scope(SCOPE_PROTOTYPE)
    public RobotFactory robotFactory() {
        return new RobotFactory() {

            @Override
            public Robot newRobot(String name) {
                return new RobotImpl(name, r2dxBrain());
            }
        };
    }

    @Bean @Scope(SCOPE_PROTOTYPE)
    public Brain r2dxBrain() {
        return new RobotBrain();
    }
}

测试代码:

public class RobotTest {

    @Test
    public void t1() throws Exception {
        ApplicationContext ctx = new 
                           AnnotationConfigApplicationContext(RobotConfig.class);
        RobotFactory rf = ctx.getBean(RobotFactory.class);
        assertThat(rf.newRobot("R2D2").toString(), 
           equalTo("RobotImpl [name_=R2D2] thins about an idea"));
    }

}

这正是 Guice 所做的。棘手的区别是Scope。 Spring 的默认范围是 Singleton 而 Guice 的不是(它是原型)。

【讨论】:

    【解决方案2】:

    AFAIK 你不能。在 Spring 中,您可以使用 Instantiation using a static factory methodInstantiation using an instance factory method。使用第二个选项,您可以定义一个 bean myFactoryBean 作为另一个 bean 的工厂。您还可以使用constructor-arg 将构造参数传递给myFactoryBean(例如参见Using An Instance Factory Method on this blog 部分),这相当于Guice 注入参数。但是,我不知道有什么方法可以在调用工厂方法时从上下文中提供更多参数。

    【讨论】:

    • 我认为你可以在 3.0 中使用 Spring-EL 做到这一点,但它开始感觉很糟糕。
    【解决方案3】:

    我终于将 Guice AsssitedInject 移植到 Spring(如果幸运的话,也可以是任何 jakarta.inject 容器)

    https://gitlab.com/wholesail-oss/assisted-inject

    检查一下,如果它对你有帮助,请告诉我:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 2018-05-05
      • 2021-02-06
      • 2020-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多