首页 > 解决方案 > 是否可以将 bean 中的重复代码提取到单个方法中?

问题描述

我有这个云网关配置,我想提取和清理任何重复的代码。

    @Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
    return builder.routes()
                  .route("post_route", r -> r.path("/api/wallet/**")
                                             .and().method("POST")
                                             .and().readBody(BankRequestData.class, requestBody -> findWalletInstance(requestBody.externalReference()).equals("localhost:3000")).uri("http://localhost:3000"))
                  .route("post_route", r -> r.path("/api/wallet/**")
                                             .and().method("POST")
                                             .and().readBody(BankRequestData.class, requestBody -> findWalletInstance(requestBody.externalReference()).equals("localhost:3001")).uri("http://localhost:3001"))

                  .build();
}

这有可能吗?我不确定是否可以做到。非常感谢任何建议或建议。先感谢您!

标签: javaspringkotlinjava-8functional-programming

解决方案


作为 Andreas 答案的变体,在 Kotlin 中,您还可以将函数定义为内部函数gatewayRoutes()

@Bean
fun RouteLocator gatewayRoutes(builder: RouteLocatorBuilder): routeLocator {

    fun walletRoute(server: String) = { r: PredicateSpec ->
        r.path("/api/wallet/**")
         .and().method("POST")
         .and().readBody(BankRequestData::class.java,
                         { findWalletInstance(it.externalReference()) == server } )
         .uri("http://$server")
    }

    return builder.routes()
                  .route("post_route", walletRoute("localhost:3000"))
                  .route("post_route", walletRoute("localhost:3001"))
                  .build()
}

或者作为初始化为匿名函数的局部变量:

@Bean
fun RouteLocator gatewayRoutes(builder: RouteLocatorBuilder): routeLocator {

    val walletRoute = fun (server: String) = { r: PredicateSpec ->
        r.path("/api/wallet/**")
         .and().method("POST")
         .and().readBody(BankRequestData::class.java,
                         { findWalletInstance(it.externalReference()) == server } )
         .uri("http://$server")
    }

    return builder.routes()
                  .route("post_route", walletRoute("localhost:3000"))
                  .route("post_route", walletRoute("localhost:3001"))
                  .build()
}

或者到一个 lambda:

@Bean
fun RouteLocator gatewayRoutes(builder: RouteLocatorBuilder): routeLocator {

    val walletRoute = { server: String -> { r: PredicateSpec ->
            r.path("/api/wallet/**")
             .and().method("POST")
             .and().readBody(BankRequestData::class.java,
                             { findWalletInstance(it.externalReference()) == server } )
             .uri("http://$server")
        }
    }

    return builder.routes()
                  .route("post_route", walletRoute("localhost:3000"))
                  .route("post_route", walletRoute("localhost:3001"))
                  .build()
}

所有这些选项都将避免向包含类添加成员,您可能会认为它更整洁——尽管这是否证明更复杂的函数体的合理性可能是个人品味的问题!

(注意:所有这些都未经测试,因为我没有相关的库,所以它可能有错误。请让我知道任何更正。希望它无论如何都能说明这些选项。)


推荐阅读