Я пытаюсь реализовать переменную ThreadLocal с помощью Spring's ThreadLocalTargetSource
, следуя примеру онлайн (и читая все, что мог), я получил эту реализацию:
open class TenantStore(var tenantId: String? = null) {
fun clear() {
this.tenantId = null
}
}
@Configuration
internal class TenancyConfiguration {
@Bean(name = ["tenantThreadLocal"], destroyMethod = "destroy")
fun threadLocalTenantStore() = ThreadLocalTargetSource().apply {
targetBeanName = "tenantStoreImpl"
}
@Primary
@Bean(name = ["proxiedThreadLocalTargetSource"])
fun proxiedThreadLocalTargetSource(threadLocalTargetSource: ThreadLocalTargetSource) = ProxyFactoryBean().apply {
targetSource = threadLocalTargetSource
}
@Bean(name = ["tenantStoreImpl"])
@Scope(scopeName = SCOPE_PROTOTYPE)
fun protoTenantStore(): TenantStore = TenantStore()
}
Это потребляется 2компоненты (синглтон), фильтр и обычный компонент.
@Component
class TenantFilter(private val tenantStore: TenantStore) : Filter {
override fun doFilter(servletRequest: ServletRequest, servletResponse: ServletResponse, filterChain: FilterChain) {
// ...
tenantStore.tenantId = tenantHeader
filterChain.doFilter(servletRequest, servletResponse)
}
@Component
class OtherComponent(private val tenantStore: TenantStore) {
fun doSomething(){
println("tenant id: ${tenantStore.tenantId}")
}
}
- В фильтре я правильно получаю прокси CGLIB
- Но в другом компоненте я не получаю. Spring внедряет новый экземпляр (из-за области действия
prototype
) в синглтон, и все, всегда один и тот же экземпляр в потоках.
Тогда
- Я могуне использовать
request
область, потому что мне нужно это для каждого потока. - Область
thread
является опцией, но я теряю пружинную обработку ThreadLocal, и мне не нужна полная область, простоэта простая структура (TenantStore).
Я ищу любую аналогичную реализацию или совет, чтобы сделать ее прозрачной для всех компонентов, которые зависят от этой переменной ThreadLocal.