Java 选择在spring运行时注入哪个实现

Java 选择在spring运行时注入哪个实现,java,spring,dependency-injection,Java,Spring,Dependency Injection,我有以下课程: public interface MyInterface{} public class MyImpl1 implements MyInterface{} public class MyImpl2 implements MyInterface{} public class Runner { @Autowired private MyInterface myInterface; } 我想做的是,在应用程序已经运行时(即启动时不是),决定应该将哪个实现注入Run

我有以下课程:

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();

实现这一点的最佳方法是什么?

声明使用
@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);
}

这种情况违背了IoC和依赖项注入的目的。您使用的是XML配置还是组件扫描?@ToddMurray所有注释驱动,完全没有XML。在启动时注入这两种内容,然后在运行时在实现之间切换。您可以使用使用spring配置的工厂模式,并在运行时选择实现。好主意。非常感谢。这是个糟糕的主意。最好调用某种返回所需实现的工厂,而不是到处散布switch语句。考虑当你需要添加一个第三实现时会发生什么?你修改了所有的代码,还是仅仅修改了工厂?如果我需要第三个IMPL,我会简单地修改这个类…顺便说一句,据我所知,spring(在>=4.0.x上测试)可以注入接口的所有实现,只需声明
@Autowired List
run(int)
将转换为:
void run(int rq){runners.get(rq.run();}
。。。请参见此处的示例:。要使运行程序的正确顺序在
MyInterface
implementation中实现
Ordered
,如果需要这样做,
资源(name=“implForRq2”)
将比限定符更好。这就是说,acc15的想法是可靠的(我现在正在做类似的事情),但工厂模式的想法可能是最好的-您注入工厂,然后通过向工厂实例方法提供一些条件,从工厂请求一个“正确的”
MyInterface
实例。实际上,是的,这是一个糟糕的想法。任何不封装创建正确类的细节的东西都有一种糟糕的代码味道。如果你不封装创建代码,你猜怎么着,你会到处都是创建代码。