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
实例。实际上,是的,这是一个糟糕的想法。任何不封装创建正确类的细节的东西都有一种糟糕的代码味道。如果你不封装创建代码,你猜怎么着,你会到处都是创建代码。