Skip to content
Advertisement

Spring: re-initialized a bean

This is my Spring bean in the configuration class that creates a gRPC ManagedChannel:

@Configuration
public class CockroachDbConfig {


 @Bean
 public ManagedChannel getManagedChannel() {
    return ManagedChannelBuilder.forTarget(CR_GRPC_SERVER)
        .usePlaintext()
        .build();
   }
 }

The controller method is provided below:

@RestController
public class DBProxyController {

    @Autowired
    private DBProxyService dbProxyService;


    @RequestMapping(value = "/", method = RequestMethod.POST,
        consumes = APPLICATION_JSON_VALUE,
        produces = APPLICATION_JSON_VALUE
    )
    @SuppressWarnings("BlockingMethodInNonBlockingContext")
    public Mono<Void> handleRequest(@RequestBody String requestBody, ServerHttpResponse serverHttpResponse, ServerHttpRequest request)  {


        org.springframework.http.HttpHeaders headers = request.getHeaders();

        Map<String, String> responseMap = dbProxyService.processRequest(requestBody, headers);

        String response = responseMap.get(X_AMZN_RESPONSE);

        if (response.equalsIgnoreCase("{}")) {
            LOGGER.info("We are ot able to sucessfully process the request and reutning an empty response");
        }

        return serverHttpResponse.writeWith(strToDataBuffer(response));
    }
}

The service class is:

@Service
public class DBProxyService {


    public Map<String, String> processRequest(final String requestBody, final org.springframework.http.HttpHeaders headers)  {


        ManagedChannel customManagedChannel = (new CockroachDbConfig()).getManagedChannel();

        switch (action) {

            case GETITEM:
            {

                // some code
                ProtoService.shutdownManagedChannel(customManagedChannel);
            }
            case PUTITEM:
            {
                // some code
                ProtoService.shutdownManagedChannel(customManagedChannel);
            }
            
        }

    }

}

For each request, I create a new ManagedChannel in the service method processRequest and shut it down using the method called shutdownManagedChannel.

Earlier, I try to use the @Autowired for the managed channel as below:

@Service
public class DBProxyService {


    @Autowired 
    private ManagedChannel customManagedChannel;

    public Map<String, String> processRequest(final String requestBody, final org.springframework.http.HttpHeaders headers)  {



        switch (action) {

            case GETITEM:
            {

                // some code
                ProtoService.shutdownManagedChannel(customManagedChannel);
            }
            case PUTITEM:
            {
                // some code
                ProtoService.shutdownManagedChannel(customManagedChannel);
            }
            
        }

    }

}

This was not successful as I shut down the channel after the completion of each request and I guess need to figure out a way to re-initialize the bean for each call.

So, how to I re-initialize the ManagedChannel for each request when the app is running?

Thanks.

Advertisement

Answer

A simple solution, not relying too much on the framework would be to inject a bean of type Supplier<ManagedChannel> (or any other functional interface type that works for your use case).

@Bean
public Suuplier<ManagedChannel> getManagedChannel() {
  return () -> ManagedChannelBuilder.forTarget(CR_GRPC_SERVER)
      .usePlaintext()
      .build();
}

And then use the get method to re-instantiate a new channel whenever you need it.

Otherwise, you could work with the scope Prototype that recreates the bean in some circumstances instead of treating it as a singleton (documentation). Be aware that injecting prototype beans in singleton beans require you to do some configuration gymnastic, as stated in the point 1.5.3 of the documentation.

Advertisement