2016-03-11 12 views
2

这是我试图实现的简化版本。 我有相同接口的多个实现。基于运行时的用户输入,我想选择正确的实现。基于运行时条件的弹簧开关实现

例如,假设我有一个名为Color的接口。有很多类实现这个接口,Red类,Blue类,Green类等等。

在运行时我需要根据用户输入选择实现。实现这一目标的一个方法是这样的

@Autowired 
@Qualifier("Red") 
private Color redColor; 

@Autowired 
@Qualifier("Green") 
private Color greenColor; 


private Color getColorImplementation() 
{ 
if(userInput=="red") 
{ 
return redColor; 

} 
else if(userInput=="green") 
{ 
return greenColor; 
} 
else 
{ 
return null; 
} 

} 

但这样做的问题是,每次一个新的实现添加,我将不得不更新采实现,它击败反转的全部目的的代码春天的控制部分。用春天做这件事的正确方法是什么?

回答

4

您可以自动连接有问题的接口的所有实现,然后根据要使用的接口提供的属性来决定。

@Autowired 
private List<Color> colors; 

public void doSomething(String input) { 
    colors.stream().filter(c -> c.getName().contains(input)).findFirst().ifPresent(c -> { 
     // something 
    } 
} 

这也是不那么神奇,更符合面向对象原则。依赖注入最初是为了连接事物,而不是在运行时进行动态切换。

+1

非常好的解决方案。你甚至可以改进它,如果你将声明'Map colors'而不是'List'。然后,应该用@Component(“colorName”)声明新的颜色。在这种情况下,您甚至可以为一种颜色创建多个同义词名称,并且不需要让“Color”类知道有关颜色分辨率的任何内容。 –

+0

@Ken:我认为你的评论应该是答案的一部分。我最终按照您的建议使用了地图,然后通过在@Component(“BeanName”)中声明的名称从地图中获取项目。完美工作! – developer747

+0

@ developer747我很乐意提供帮助。主要思想 - 根据基本类型自动调整bean的列表,由zapl建议。其他它只是细节。 –

2

您想自动填入ApplicationContext,那么您可以通过Map<String, Color> colors = appContext.getBeansOfType(Color.class);获得所有Color豆。这假定userInput和bean名称是相同的。

如果不是这种情况,解决方案是将getName()添加到Color接口;那么你可以自动装配一个List<Color>并自己构建Map。

难道你不能让颜色变成枚举吗?

+0

这是一种可以接受的做法吗?调用appContext来获取bean?但它听起来像是个好主意。我可能会这样做。 – developer747

+0

AppContext已经存在并且是自动编译的,所以不需要额外的工作。请记住,您只需要在bean的构造函数中或者在@ @ PostConstruct中执行此操作。 –

1

春季ServiceLocatorFactoryBean(向下滚动到中间)API建只是为了这个目的:

  1. 创建一个虚拟接口(ColorFactory),其提供了这样一个方法Color getColor(String color)
  2. 创建代理bean实例org.springframework.beans.factory.config.ServiceLocatorFactoryBean通过ColorFactory作为serviceLocatorInterface参数
  3. 定义所有颜色实现的beans,其名称与您想要传递的参数匹配getColor
  4. 注入出厂到合作者,并根据需要

你可以在ApplicationContext类似的API图谋这个调用getColor,但这种方法的好处是,它抽象春天从Java实现(XML配置项目)。

+0

以下是示例http://www.jcombat。com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring – user3198603