Spring Mono<User> 作为构造函数参数 - 如何 "cache" 对象
Spring Mono<User> as constructor param - how to "cache" object
我对如何使用 Spring Boot 在项目反应堆中执行此操作一无所知:
class BakerUserDetails(val bakerUser: Mono<BakerUser>): UserDetails {
override fun getPassword(): String {
TODO("Not yet implemented")
// return ???.password
}
override fun getUsername(): String {
TODO("Not yet implemented")
// return ???.username
}
}
我该如何进行这项工作?我是只放 bakerUser.block().password
和 bakerUser.block().username
以及所有这些方法,还是有更好的方法来实现这些方法?
目前,我正在做这样的事情,但看起来很奇怪:
private var _user: BakerUser? = null
private var user: BakerUser? = null
get() {
if(_user == null){
_user = bakerUser.block()
}
return _user
}
override fun getAuthorities(): MutableCollection<out GrantedAuthority> {
return mutableSetOf(SimpleGrantedAuthority("USER"))
}
override fun getPassword(): String {
return user!!.password!!
}
我不太精通 Kotlin,但我可以告诉你,你不应该将 Mono
传递给 UserDetails
对象。
A Mono<T>
有点像 future/promise。这意味着里面什么都没有。所以如果你想从中得到一些东西,你可以 block
这意味着我们等待,直到里面有东西,或者我们订阅,这基本上意味着我们等待 async
直到里面有东西。这可能很糟糕。把它想象成兼职工作。如果您开始一项工作并退出程序会发生什么,那么该工作将不会执行。
或者你做了一些线程化的事情,然后程序 returns/exits,主线程死了,所有线程都死了,什么也没发生。
我们通常在反应世界中谈论 Publishers
和 Consumers
。所以 Flux/Mono
是 Publisher
然后你声明一个 pipeline
来说明解决问题时会发生什么。并启动 consumer
需要 subscribe
到 producer
的过程。
通常在服务器世界中,这意味着发出请求的网页是 consumer
并且它 subscribes
到服务器,在这种情况下是 publisher
.
所以我要说的是,您几乎不应该 subscribe
在您的应用程序中,除非您的应用程序是启动消费的应用程序。例如,您的服务器中有一个 cron 作业会占用另一台服务器等。
让我们看看你的问题:
您还没有发布您的代码,所以我要在这里做一些猜测,但我猜您是从数据库中获取用户。
public Mono<BakerUserDetails> loadUserByUsername(String username) {
Mono<user> user = userRepository.findByUsername(username);
// Here we declare our pipline, flatMap will map one object to another async
Mono<BakerUserDetails> bakerUser = user.flatMap(user -> Mono.just(new BakerUserDetails(user));
return bakerUser;
}
我在没有编译器的情况下写了这篇文章。
所以不要传入 Mono<T>
使用不同的运算符(例如 map
或 flatMap
等进行转换。除非您的服务器是最终消费者,否则不要订阅您的应用程序。
我对如何使用 Spring Boot 在项目反应堆中执行此操作一无所知:
class BakerUserDetails(val bakerUser: Mono<BakerUser>): UserDetails {
override fun getPassword(): String {
TODO("Not yet implemented")
// return ???.password
}
override fun getUsername(): String {
TODO("Not yet implemented")
// return ???.username
}
}
我该如何进行这项工作?我是只放 bakerUser.block().password
和 bakerUser.block().username
以及所有这些方法,还是有更好的方法来实现这些方法?
目前,我正在做这样的事情,但看起来很奇怪:
private var _user: BakerUser? = null
private var user: BakerUser? = null
get() {
if(_user == null){
_user = bakerUser.block()
}
return _user
}
override fun getAuthorities(): MutableCollection<out GrantedAuthority> {
return mutableSetOf(SimpleGrantedAuthority("USER"))
}
override fun getPassword(): String {
return user!!.password!!
}
我不太精通 Kotlin,但我可以告诉你,你不应该将 Mono
传递给 UserDetails
对象。
A Mono<T>
有点像 future/promise。这意味着里面什么都没有。所以如果你想从中得到一些东西,你可以 block
这意味着我们等待,直到里面有东西,或者我们订阅,这基本上意味着我们等待 async
直到里面有东西。这可能很糟糕。把它想象成兼职工作。如果您开始一项工作并退出程序会发生什么,那么该工作将不会执行。
或者你做了一些线程化的事情,然后程序 returns/exits,主线程死了,所有线程都死了,什么也没发生。
我们通常在反应世界中谈论 Publishers
和 Consumers
。所以 Flux/Mono
是 Publisher
然后你声明一个 pipeline
来说明解决问题时会发生什么。并启动 consumer
需要 subscribe
到 producer
的过程。
通常在服务器世界中,这意味着发出请求的网页是 consumer
并且它 subscribes
到服务器,在这种情况下是 publisher
.
所以我要说的是,您几乎不应该 subscribe
在您的应用程序中,除非您的应用程序是启动消费的应用程序。例如,您的服务器中有一个 cron 作业会占用另一台服务器等。
让我们看看你的问题:
您还没有发布您的代码,所以我要在这里做一些猜测,但我猜您是从数据库中获取用户。
public Mono<BakerUserDetails> loadUserByUsername(String username) {
Mono<user> user = userRepository.findByUsername(username);
// Here we declare our pipline, flatMap will map one object to another async
Mono<BakerUserDetails> bakerUser = user.flatMap(user -> Mono.just(new BakerUserDetails(user));
return bakerUser;
}
我在没有编译器的情况下写了这篇文章。
所以不要传入 Mono<T>
使用不同的运算符(例如 map
或 flatMap
等进行转换。除非您的服务器是最终消费者,否则不要订阅您的应用程序。