给定一个特定服务API的两个(或多个)实现,基于应用程序属性在我的应用程序中选择在运行时使用哪一个的最佳方法是什么?
示例API:
public interface Greeting {
String sayHello(String username);
}
实施:
public class FriendlyGreeting implements Greeting {
public String sayHello(String username) {
return "Hello, " + username;
}
}
public class HostileGreeting implements Greeting {
public String sayHello(String username) {
return "Go away, " + username;
}
}
我有一个带有@Autowired
构造函数的独立服务类,该构造函数采用Greeting
的实例。我想要的是基于配置属性,以确定要注入和使用的问候语实现。我想出了使用配置类做出决定的方法:
@Configuration
public class GreetingConfiguration {
private String selection;
@Autowired
public GreetingConfiguration(@Value("${greeting.type}") String type) {
this.selection = type;
}
@Bean
public Greeting provideGreeting() {
if ("friendly".equals(selection)) {
return new FriendlyGreeting();
} else {
return new HostileGreeting();
}
}
}
这是正确做我想要的事情的方法吗?我走过在实现上使用@Qualifier
的道路,最后陷入一片混乱,Spring看到了我的Greeting
API的3个实例,无论如何我都需要一个配置来选择要使用并返回的实现它上面有一个唯一的限定词名称,这感觉比我确定的要差。
答案 0 :(得分:1)
您可以使用https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Conditional.html和https://reflectoring.io/spring-boot-conditionals/
中描述的Array
注解
上面提到的 @Conditional
注释基于@Profile
(来自Spring Framework);另请参阅Spring Boot:org.springframework.boot.autoconfigure.condition
答案 1 :(得分:0)
您可以将Greeting都标记为@Service,并使用@Qualifier(“ yourServiceHere”)选择所选择的一个,如下所示:
@Autowired
@Qualifier("friendlyGreeting")
private Greeting greeting;
另一种方法是使用个人资料。您可以使用@Service和@Profile(“ friendly”)标记您的FriendlyGreeting服务,并使用@Service和@Profile(“ hostileGreeting”)标记HostileGreeting服务,然后将以下内容放入application.properties:
spring.profiles.active=friendly
答案 2 :(得分:0)
回答我自己的问题。
@Compass和@user268396是正确的-使用“个人档案”可以按预期工作。
我创建了两个实现,并用@Service和@Profile(“ friendly”)或@Profile(“ hostile”)进行了注释,并且可以将属性spring.profiles.active
更改为dev,friendly
,并获得我想要的。
答案 3 :(得分:0)
这是一个完整的解决方案,使用上面 David 和 Vitor 提到的想法以及@Profile 和 @Qualifer 注释。
两个具有相同名称的 bean,但根据定义的配置文件仅激活一个 bean。
@Profile("profile1")
@Bean("greeting")
public class FriendlyGreeting implements Greeting {
---
@Profile("profile2")
@Bean("greeting")
public class HostileGreeting implements Greeting {
---
@Configuration
public class GreetingConfiguration {
private Greeting greeting;
@Autowired
public GreetingConfiguration(@Qualifier("greeting") Greeting greeting) {
this.greeting = greeting;
}
}
注意事项:
GreetingConfiguration
并将“greeting”bean 粘贴到您需要的任何位置