java决定在Spring Boot应用程序中使用多个实现中的哪一个
给定特定服务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个实例,我需要一个配置来选择要使用的实现并返回一个唯一的限定符名称,这感觉比我确定的更糟
# 1 楼答案
下面是一个完整的解决方案,它使用了上面David和Vitor提到的带有@Profile和@qualifier注释的想法
两个名称相同但只有一个bean根据定义的配置文件激活
注:
GreetingConfiguration
,并将“问候”bean粘贴到任何需要的地方# 2 楼答案
您可以将两种问候语都标记为@Service,并用@Qualifier(“yourServiceHere”)选择所选的问候语,如下所示:
另一种方法是使用profile。你可以用@service和@Profile(“FriendlyGreeting”)标记你的FriendlyGreeting服务,用@service和@Profile(“HostileGreeting”)标记HostileGreeting服务,然后输入应用程序。属性如下:
# 3 楼答案
回答我自己的问题
@Compass和@user268396是正确的——使用概要文件可以如期工作
我创建了两个实现,用@Service和@Profile(“友好”)或@Profile(“敌对”)进行注释,并可以将属性
spring.profiles.active
更改为dev,friendly
,例如,获得我想要的# 4 楼答案
您可以使用https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Conditional.html和https://reflectoring.io/spring-boot-conditionals/中描述的
@Conditional
注释上面提到的}
@Profile
注释基于@Conditional
(来自Spring框架);另请参见Spring Boot:^{