如何根据属性很好地连接具有不同实现的bean?

时间:2017-08-08 05:59:17

标签: java spring spring-boot

我目前正在寻找一种更好的解决方案来连接不同实现的bean。具体实现取决于提供的application.properties,它从一个阶段变为阶段。

让我们来看看具体的课程:

  • 界面: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 个答案:

答案 0 :(得分:0)

正如@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将被配置为profile" dev"不再被激活。