Hot questions for Using RxJava 2 in spring

Question:

My application is listening to an exchange (using rabbitMQ), expecting to receive some API data and then should redirect it to the relevant place.

I'm using rxJava to subscribe on these changes, when the purpose is to open a new thread and send the request by creating RestClient each time -> it will receive the data, parse it, send it and then send the response back to queue.

My problem is that I want each time to create a new instance of my RestClient. Thought of using Springs Scope annotation : @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) but can't seem to understand how to use it and what will be the difference if I use new RestClient each time.

Can you please explain the advantage of using getBean over using new?

Here is the code:

class MyManager {

   @Autowired
   private WebApplicationContext context;
    ....
    ...
    ...

    @PostConstruct
    myListener.subscribeOn(Schedulers.computation()).subscribe(this::handleApiRequest);


    private void  handleApiRequest(ApiData apiData){

    // Option 1:
    RestClient client = new RestClient();
    client.handleApiRequest(apiData);

    //Option 2:
    // use somehow the prototype?
    RestClient x = (RestClient)context.getBean("restTest")..
    }
}



 @Service
 //@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) //NEEDED??
class RestClient {
 private String server;
  private RestTemplate rest;
  private HttpHeaders headers;
  ResponseEntity<String> responseEntity;

  @PostConstruct
  private void updateHeaders() {
    headers.add(Utils.CONTENT_TYPE, Utils.APPLICATION_JSON);
    headers.add(Utils.ACCEPT, Utils.PREFIX_ALL);
  }


  public void handleApiRequest(ApiData apiRequest) {
    sendRequest(apiRequest); //implemented
    sendResponse(); //implemented
  }


}


  @Bean(name = "restTest")
  @Scope("prototype")
  public RestClient getRestTemplate() {
    return new RestClient();
  }

Answer:

First of all, resttemplate is thread-safe. Don't instantiate it per request or using new keyword (Constructor), that is a bad design. Because you commented out @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) here; and by default, spring will create a singleton bean of RestClient and you will get the same instance of RestClient wherever you autowire; so you are doing it right.

@Service
 //@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) //NEEDED??
class RestClient {

I have a question here though, in RestClient, where are you instantiating private RestTemplate rest; I am not seeing that in the code that you posted

And if you are moving to singleton scope from prototype scope as suggested, you can use @Autowired RestClient restClient;

instead of

@Autowired private WebApplicationContext context;
RestClient x = (RestClient)context.getBean("restTest")

Less boilerplate.

Question:

So I am using Spring Data Cassandra and RxJava, I am looking for a way to use RxJava Observable with custom query building (the find..by abstraction is to complicated to use in my case) and I was planning on using QueryDSL (the method findAll(Predicate), but it does not enable Async :/)

So far my best shot is to use AsyncCassandraTemplate to build a Query and return it as ListenableFuture so that it can be mapped to a Observable and be used with RxJava's Observable. Is there any other way?


Answer:

There's no QueryDsl support Spring Data for Apache Cassandra. You can use Query objects to create queries and ReactiveCassandraTemplate for reactive API usage:

Mono<Person> person = cassandraTemplate.selectOneById(query(where("age").is(33)), Person.class);
Maybe<Person> maybe = Flowable.fromPublisher(person).firstElement();