spring - Spring Boot中基于​​表达式的Autowire(使用Kotlin)

标签 spring spring-boot kotlin spring-el

情况

我正在尝试提出一种方法来有条件地加载一个bean(基于2个属性或环境变量的存在),如果缺少它们,则加载另一个bean。

Vars

因此,这两个属性(或env vars)是:

  • ProtocolHOST
  • ProtocolPORT

  • 因此,例如java -jar xxxx -DProtocolHost=myMachine -DProtocolPort=3333将使用我想要的bean,但是如果两者都缺失,那么您将获得另一个bean。
    @Component("Protocol Enabled")
    class YesBean : ProtocolService {}
    
    @Component("Protocol Disabled")
    class NoBean : ProtocolService {
    

    稍后在我的 Controller 中,我有一个:
    @Autowired
    private lateinit var sdi : ProtocolService
    

    因此,我研究了多种选择:

    同时使用@ConditionalOnProperty@ConditionalOnExpression,我似乎无法取得任何进展。

    我敢肯定,我需要走 Expression 路线,所以我写了一些似乎失败的测试代码:
    @PostConstruct
    fun customInit() {
        val sp = SpelExpressionParser()
        val e1 = sp.parseExpression("'\${ProtocolHost}'")
        println("${e1.valueType}   ${e1.value}")
        println(System.getProperty("ProtocolHost")
    }
    

    哪个返回:

    class java.lang.String ${ProtocolHost} taco



    因此,我不确定 SPeL 解析是否正常工作,因为看起来它只是返回字符串“$ {ProtocolHost}”,而不是处理正确的值。我假设这就是为什么我在“表达语言”中所做的所有尝试均失败的原因,因此也被困住了。

    任何援助将不胜感激!

    谢谢

    更新资料

    我确实做到了以下几点

    在我的主要:
     val protocolPort: String? = System.getProperty("ProtocolPort", System.getenv("ProtocolPort"))
     val protocolHost: String? = System.getProperty("ProtocolHost", System.getenv("ProtocolHost"))
    
     System.setProperty("use.protocol", (protocolHost != null && protocolPort != null).toString())
     runApplication<SddfBridgeApplication>(*args)
    

    然后在bean定义上:
    @ConditionalOnProperty(prefix = "use", name = arrayOf("protocol"), havingValue = "false", matchIfMissing = false)
    
    @ConditionalOnProperty(prefix = "use", name = arrayOf("protocol"), havingValue = "false", matchIfMissing = false)
    

    但是,这感觉像是一种破解,我希望可以直接在SpEL中完成,而不是预先设置vars。

    最佳答案

    对于基于Java的bean配置,这听起来像是一个完美的用例:

    @Configuration
    class DemoConfiguration {
    
        @Bean
        fun createProtocolService(): ProtocolService {
            val protocolPort: String? = System.getProperty("ProtocolPort", System.getenv("ProtocolPort"))
            val protocolHost: String? = System.getProperty("ProtocolHost", System.getenv("ProtocolHost"))
            return if(!protocolHost.isNullOrEmpty() && !protocolPort.isNullOrEmpty()) {
                YesBean()
            } else {
                NoBean()
            }
        }
    
    }
    
    open class ProtocolService
    
    class YesBean : ProtocolService()
    
    class NoBean : ProtocolService()
    

    您可能还想研究Externalized Configurations来替换System.getProperty()System.getenv()

    然后将如下所示:
    @Configuration
    class DemoConfiguration {
    
        @Bean
        fun createProtocolService(@Value("\${protocol.port:0}") protocolPort: Int,
                                  @Value("\${protocol.host:none}") protocolHost: String): ProtocolService {
            return if (protocolHost != "none" && protocolPort != 0) {
                YesBean()
            } else {
                NoBean()
            }
        }
    
    }
    

    关于spring - Spring Boot中基于​​表达式的Autowire(使用Kotlin),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53043564/

    相关文章:

    java - 在sts嵌入的apache tomcat服务器无法启动

    java - 从 messages.properties 访问 application.properties

    spring - 如何使用基本身份验证保护 spring cloud eureka 服务?

    kotlin - Gradle Kotlin脚本,尝试通过内置变量分配classpatch

    java - 如何使用 Spring Data JPA 获得域驱动设计架构?

    spring - 在 TestRestTemplate 中启用 Cookie 和重定向

    java - Apache Camel RouteBuilder 配置方法

    java - 如何在传统的spring mvc应用程序中添加请求超时或连接超时来防止“''慢http post漏洞”?

    java - 云Firestore : Add Field Value To Document

    Kotlin:删除数组中相同的相邻成员