有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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看到了我的GreetingAPI的3个实例,我需要一个配置来选择要使用的实现并返回一个唯一的限定符名称,这感觉比我确定的更糟


共 (4) 个答案

  1. # 1 楼答案

    下面是一个完整的解决方案,它使用了上面David和Vitor提到的带有@Profile和@qualifier注释的想法

    两个名称相同但只有一个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,并将“问候”bean粘贴到任何需要的地方
    • 我更喜欢构造函数上的@Autowired,而不是类成员,以便于单元测试
  2. # 2 楼答案

    您可以将两种问候语都标记为@Service,并用@Qualifier(“yourServiceHere”)选择所选的问候语,如下所示:

    @Autowired
    @Qualifier("friendlyGreeting")
    private Greeting greeting;
    

    另一种方法是使用profile。你可以用@service和@Profile(“FriendlyGreeting”)标记你的FriendlyGreeting服务,用@service和@Profile(“HostileGreeting”)标记HostileGreeting服务,然后输入应用程序。属性如下:

    spring.profiles.active=friendly
    
  3. # 3 楼答案

    回答我自己的问题

    @Compass@user268396是正确的——使用概要文件可以如期工作

    我创建了两个实现,用@Service和@Profile(“友好”)或@Profile(“敌对”)进行注释,并可以将属性spring.profiles.active更改为dev,friendly,例如,获得我想要的