Autowire на основе выражений в Spring Boot (с Kotlin) - PullRequest
0 голосов
/ 29 октября 2018

Положение

Я пытаюсь найти методологию для условной загрузки одного компонента (на основе наличия двух переменных свойства или среды) и, если они отсутствуют, загружает другой компонент.

Варс

Итак, два свойства (или env vars):

  • ProtocolHOST
  • ProtocolPORT

Так, например, java -jar xxxx -DProtocolHost=myMachine -DProtocolPort=3333 будет использовать нужный мне боб, но если оба будут отсутствовать, вы получите другой бин.

@Component("Protocol Enabled")
class YesBean : ProtocolService {}

@Component("Protocol Disabled")
class NoBean : ProtocolService {

Позже в моем контроллере у меня есть:

@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")
}

Что возвращает:

класс java.lang.String $ {ProtocolHost} тако

Так что я не уверен, что мой 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)

А потом по определению бина:

@ConditionalOnProperty(prefix = "use", name = arrayOf("protocol"), havingValue = "false", matchIfMissing = false)

@ConditionalOnProperty(prefix = "use", name = arrayOf("protocol"), havingValue = "false", matchIfMissing = false)

Однако это похоже на взлом, и я надеюсь, что это может быть сделано непосредственно в SpEL вместо предустановок в зависимости от времени.

1 Ответ

0 голосов
/ 29 октября 2018

Это звучит как идеальный вариант использования для конфигурации bean-компонентов на Java:

@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()

Возможно, вы также захотите просмотреть Внешние конфигурации , чтобы заменить 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()
        }
    }

}
...