有 Java 编程相关的问题?

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

java如何根据属性将bean与不同的实现连接起来?

我目前正在寻找一个更好的解决方案,用不同的实现连接bean。具体实现取决于提供的应用程序。属性,这些属性随阶段的不同而变化

让我们看看具体的类:

  • 接口:FtpWriter
  • 实现:SftpWriter、DefaultFtpWriter

通常我会这样做:

@Bean
@ConfigurationProperties("writer.ftp")
public FtpWriter getWriter() {
    return new DefaultFtpWriter();
}

但在这里,我必须使用一个特定的实现如何实现上述部分以考虑属性并选择正确的实现

我提出了一个解决方案:

@Bean("writer1")
public FtpWriter oneWriter( 
        @Value("${writer1.ftp.username}") String username, 
        ...) {
    return this.getWriter(username, password, protocol, url, port, path);
}

private FtpWriter getWriter(String username, String password, String protocol, String URL, int port, String path) {
    FtpWriter writer;
    if ("sftp".equals(protocol)) {
        writer = new SftpWriter(username, password, protocol, url, port, path);
    } else {
        writer = new DefaultFtpWriter(username, password, protocol, url, port, path);
    }

    return writer;
}

对我来说,通过@Value作为方法参数直接加载属性似乎有点难看


共 (1) 个答案

  1. # 1 楼答案

    正如@Leffchik已经建议的,我还建议在本例中使用Spring概要文件。听起来,它们非常适合您的需要,即使我不知道您的确切上下文和影响运行时环境的限制。但是参考文档中的相关部分可能会帮助您找到更好的方法来面对您的问题:https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-definition-profiles

    我同意您的观点,您的解决方案可能会起作用,但Spring概要文件将带来更干净的代码,因为您将按照以下方式配置bean:

    @Configuration
    public class FtpConfiguration() {
    
        @Value("${writer1.ftp.username}")
        private String username;
    
        // more properties needed for creating writer instances
        // ...
    
        @Bean
        @Profile("dev")
        public FtpWriter defaultFtpWriter() {
            return new DefaultFtpWriter(username, ...);
        }
    
        @Bean
        @Profile("!dev")
        public FtpWriter sftpFtpWriter() {
            return new SftpWriter(username, ...);
        }
    
    }
    

    我假设您可能会在本地开发环境中使用DefaultFtpWriter,也可能在第一个测试阶段使用。从上面的阶段开始,您可能会使用SftpWriter。“以这种方式配置写入”解决了您所说的有关属性的问题,这些属性将不会由您自己维护(无论如何,我认为您将能够在本地开发时控制这些属性,并且希望在早期(自动)测试的环境中控制这些属性)。唯一需要做的是,在需要DefaultFtpWriter时激活相应的配置文件。在本例中,您将提供一个系统环境变量spring.profiles.active="dev"

    即使您无法控制属性,也应该能够在某些阶段设置此系统变量(例如,在服务器启动时设置为JVM参数:-Dspring.profiles.active="dev")。在接近生产的阶段,您甚至可能不需要配置任何东西,因为SftpWriter将被配置,因为概要文件“dev”不再被激活