0

I'm trying to understand what is the right way of implementing post_construct methods in Spring Webflux. On startup of an application I need to read data from the DB (I have an R2dbcRepository configured), and then perform some logic and save result as Bean's fields).

So I have a findAll() method returning Flux. How should it be done?

I tried using .block(), AtomicBoolean flag, none of these worked

Ilya G.
  • 61
  • 7

1 Answers1

1

First of all, never use block() method. Use it for tests at most, but there is a better solution out there than StepVerifier. (If you use Kotlin there are await prefixed methods that work like block but not blocking.)

If you need data at launch, that says it is bad design to me because if there is no user, what do you do with it? I think it's illogical. What happens when you use query when you need it, add to cache and reuse it when you need it again. In the case of WebFlux, you can prepare a Mono object that uses a query from the database and use .cache() end of chain. So Spring Bean can contain this Mono object that will be run when you subscribe.

Ofc below example, repo.find will never call if function of Service won't run.

https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#cache--

@Configuration
public class Config {
    private R2dbcRepository repo;
    
    public Config(R2dbcRepository repo) {
        this.repo = repo;
    }

    @Bean
    public Mono<Data> myCachedDbData() {
        return repo.find(...)
            .map(it -> new Data(it))
            .cache()
    }
}

@Service
public class Service {
    private Mono<Data> data;
    
    public Config(Mono<Data> data) {
        this.data = data;
    }


    public Object function() {
        return data.flatMap(...)
    }
}
Numichi
  • 926
  • 6
  • 14
  • Thanks for your answer! I guess it's a good solution, but not exactly what I need. I need a blocking call, as I want my bean to contain a calculated value instead of Mono, as I will use it later in the .map() function. I guess my usage of reactive might not be fully correct, but that's what I need now. I somehow succeeded with this solution: https://stackoverflow.com/questions/61035588/reactive-calls-in-postconstruct-function. It uses a scheduler, and I've extended it with stopping the scheduler when my logic is done. It works, but looks ugly. – Ilya G. Nov 28 '22 at 10:27
  • 1
    You can see that block is not correct usage. You can use config attribute via subscribe, as in linked example. It is okay, just need a complete or error signal in Mono/Flux flow, or it will always be listening. So there will be a memory leak for you and will never be released. – Numichi Nov 28 '22 at 11:40