【问题标题】:Choose which implementation to inject at runtime spring选择在运行时注入哪个实现 spring
【发布时间】:2013-10-07 18:21:17
【问题描述】:

我有以下课程:

public interface MyInterface{}

public class MyImpl1 implements MyInterface{}

public class MyImpl2 implements MyInterface{}

public class Runner {
        @Autowired private MyInterface myInterface;
}

我想做的是决定,当应用程序已经在运行时(即不是在启动时)应该将哪个实现注入Runner

理想情况下是这样的:

ApplicationContext appContext = ...
Integer request = ...

Runner runner = null;
if (request == 1) {
        //here the property 'myInterface' of 'Runner' would be injected with MyImpl1
        runner = appContext.getBean(Runner.class) 
}
else if (request == 2) {
        //here the property 'myInterface' of 'Runner' would be injected with MyImpl2
        runner = appContext.getBean(Runner.class)
}
runner.start();

最好的方法是什么?

【问题讨论】:

  • 这种方式违背了 IoC 和依赖注入的目的。
  • 您是在使用 XML 配置还是组件扫描?
  • @ToddMurray 所有注释驱动,根本没有 XML。
  • 在启动时同时注入,然后在运行时在实现之间切换。
  • 您可以使用使用 spring 配置的工厂模式并在运行时选择实现。

标签: java spring dependency-injection


【解决方案1】:

使用@Component("implForRq1")@Component("implForRq2") 声明实现

然后将它们都注入并使用:

class Runner {

    @Autowired @Qualifier("implForRq1")
    private MyInterface runnerOfRq1;

    @Autowired @Qualifier("implForRq2")
    private MyInterface runnerOfRq2;

    void run(int rq) {
        switch (rq) {
            case 1: runnerOfRq1.run();
            case 2: runnerOfRq2.run();
            ...

        }
    }

}

...

@Autowired
Runner runner;

void run(int rq) {
    runner.run(rq);
}

【讨论】:

  • 好主意。非常感谢。
  • 这是个糟糕的主意。最好调用某种返回所需实现的工厂,而不是到处散布 switch 语句。考虑一下当您需要添加第三个实现时会发生什么 - 您是修改所有代码,还是只修改工厂?
  • 如果我需要第三个 impl 我将简单地修改这个类...顺便说一句,现在,据我所知 spring(在 >= 4.0.x 上测试)可以注入接口的所有实现,只需声明@Autowired List<MyInterface>run(int) 将转换为:void run(int rq) { runners.get(rq).run(); }...参见此处的示例:nurkiewicz.com/2015/04/…。为了使跑步者的正确顺序在MyInterface实现中实现Ordered
  • 如果你需要这种方式,Resource (name = "implForRq2") 会比限定符更好。也就是说,acc15 的想法是可靠的(我现在正在做类似的事情),但是工厂模式的想法可能是最好的——你注入工厂,然后通过提供一些标准来从工厂请求一个“正确的”MyInterface 实例工厂实例方法。
  • 实际上,是的,这是一个糟糕的主意。任何没有封装创建正确类的细节的东西都会产生不好的代码味道。如果你不封装创建代码,你猜怎么着,你将到处都有创建代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-16
  • 2019-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
相关资源
最近更新 更多