Search code examples
javaspring-cloud-gatewayspring-cloud-loadbalancer

Why is the bean 'reactorServiceInstanceLoadBalancer' instantiated just when the method 'getInstance' is called?


Im trying to define a custom LoadBalancer by implementation the interface ReactorServiceInstanceLoadBalancer to replace the default load balancer defined by RoundRobinLoadBalancer.

But it doesn't work.

I found that the original bean defined in class 'LoadBalancerClientConfiguration' isn't instantiated when the application startup,but instantiated when 'LoadBalancerClientFactory.getInstance' is called, and the contructor is autowired with a bean of StandardEnvironment, while the bean defined in my configuration is instantiated when the application startup, and autowired with a bean of StandardReactiveWebEnvironment.

Very confused! My english is not so good.Thank you for reading the whole description! Here is my code below:

    `@Slf4j
public class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    // ...detail omitted
}

@Configuration(proxyBeanMethods = false)
@ConditionalOnDiscoveryEnabled
public class CustomLoadBalancerClientConfiguration {
    @Bean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory, ServiceInstanceChooser serviceInstanceChooser) {
        String name = loadBalancerClientFactory.getName(environment);
        return new CustomLoadBalancer(serviceInstanceChooser, loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

Solution

  • A separate context, including the ReactorServiceInstanceLoadBalancer instance is created per requested serviceId. It is possible, to provide your own implementation, both default or for a specific service. Please see the documentation on how to provide custom configuration for Spring Cloud LoadBalancer.